Puis-je écrire des scripts en C ++?


Récemment, j'ai dû plonger à nouveau dans le monde merveilleux de la programmation de scripts Linux. En principe, la question n'est pas très délicate, mais comme je rencontre souvent de telles tâches, je les étudie à chaque fois. Je sais avec certitude que demain j'oublierai beaucoup et dans un mois je vais à nouveau google comment faire ceci ou cela. Le problème se révèle toujours que souvent vous n’écrivez pas à nouveau le script, mais vous modifiez celui déjà écrit par quelqu'un. Et ce n'est peut-être pas bash, mais sh ou autre chose ... Il y a des différences dans la syntaxe, ce qui fonctionne dans sh devrait fonctionner dans bash, mais pas toujours l'inverse. Et s'il y a du tiret ou de la cendre? Je ne sais pas ... Il y a encore des différences dans ces langages de script, et ils prêtent à confusion. Et bien sûr, pour moi personnellement, la cerise sur le gâteau lorsque le script appelle un sed ou un awk et qu'il y a de tels paramètres sur la ligne de commande que vous les regardez et vous vous demandez.Il est clair que tout cela dépend des qualifications du programmeur, mais tout ne rentre pas dans ma tête. Et maintenant ma patience est partie et je pensais qu'à partir de maintenant je veux essayer d'écrire des scripts en c ++ ...

Je comprends que pour un vrai administrateur système, ma pensée peut sembler séditieuse. Mais pourquoi pas?

L'idée est donc très simple. Je veux écrire des scripts c ++ de la même manière que les scripts réguliers sont écrits, c'est-à-dire que la première ligne du script devrait contenir shebang et une indication du chemin vers "l'interpréteur":

#!/bin/c++

Les lignes suivantes du script ne seront qu'un programme c ++ normal.

Je dois préparer "l'interpréteur" du script c ++. Vous pouvez l'écrire sur n'importe quoi, au moins sur bash (c'est la dernière fois, mais pas exactement). Bien sûr, ce ne sera pas un interprète, mais un compilateur.

C'est ce que j'ai fait:

#!/bin/bash

msg_file=/dev/null
#msg_file=/dev/stdout

tmp_path=$HOME"/.cache/c++/"
mkdir -p $tmp_path
tmp_file=$1".c++"
exe_file=$1".bin"
if test $1 -nt  $tmp_path$exe_file; then
    echo "Need to recompile.." > $msg_file
    tail -n +2 $1 > $tmp_path$tmp_file
    eval "g++ -o $tmp_path$exe_file $tmp_path$tmp_file > /dev/null 2>&1"
    if [ $? -eq 0 ]
    then
	echo "Compiled ok" > $msg_file
    else
	echo "Compile error" > $msg_file
	exit 255
    fi
fi
eval "$tmp_path$exe_file $@1"

Ce script fait tout ce dont vous avez besoin. En tant que dossier temporaire, j'ai choisi le dossier ~ / .cache / c ++. Le script d'origine sera copié dans ce dossier, mais sans la première ligne avec shebang. Cela se fait par la commande tail. Le nom du nouveau fichier sera comme le script d'origine, mais avec l'extension c ++. Le binaire avec l'extension .bin sera collecté dans le même dossier. Mais d'abord, bien sûr, une vérification «si test» est effectuée au moment de la création du binaire. La compilation ne se produit que si le binaire existant est obsolète dans le temps par rapport au «script» d'origine. Le binaire est lancé avec la commande eval et tous les paramètres initiaux lui sont passés.

Ce fichier c ++ doit être copié dans le dossier / bin et rendu exécutable (chmod a + x).

Je vais essayer d'écrire mon premier "script c ++":

#!/bin/c++

#include <stdio.h>
#include <iostream>

using namespace std;

int main( int argc, char *argv[] )
{
    cout << "hello world!\n";
    for( int i=0; i<argc; i++)
    {
	cout << "Param" << i <<  " is " << argv[i] << "\n";
    }
    return 60+argc;
}

Ce programme imprime simplement une liste de paramètres d'entrée et renvoie leur nombre + 60. Je
lance mon "script":



ça marche !!!

Si vous faites une erreur dans le code c ++, le programme ne démarrera pas, car il ne compilera pas, mais écho $? reviendra 255. Mais c'était ce qui était prévu.

L'utilisation de c ++ offre d'énormes opportunités. Tout d'abord, la syntaxe familière. Deuxièmement, les classes standard comme std :: vector, std :: map ou std :: string et d'autres sont des choses irremplaçables. La même ligne - tout ce que vous voulez en faire, regardez dans la ligne, divisez-la en sous-chaînes, déconnectez-vous et conquérez, obtenez des tableaux. Et je n'ai besoin ni de sed ni d'awk. Troisièmement, le débogueur - Dieu! quelle bénédiction! J'ai un débogueur gdb pour le script! De plus, vous pouvez utiliser std :: filesystem (si le compilateur le permet). Vous pouvez continuer ...

Malheureusement, il m'arrive souvent de le faire en premier, puis je pense: "Et si quelqu'un l'a déjà fait?" Et en fait, je ne suis pas le premier à avoir l'idée de faire de même. Voici un exemple: https://github.com/dimgel/cpp-linux-scripts l' idée est la même, l'implémentation est différente. Ensuite, il s'est avéré qu'il existe d' autres implémentations .

En général, j'ai vécu une légère déception dans ma propre non-exclusivité. Cependant, j'ai cherché Habr - je n'en ai pas trouvé un semblable. Peut-être que quelqu'un semble au moins curieux?

All Articles