Kann ich Skripte in C ++ schreiben?


Vor kurzem musste ich immer wieder in die wunderbare Welt der Linux-Skriptprogrammierung eintauchen. Im Prinzip ist die Sache nicht sehr schwierig, aber da ich nicht oft auf solche Aufgaben stoße, studiere ich sie jedes Mal neu. Ich weiß mit Sicherheit, dass ich morgen viel vergessen werde und in einem Monat werde ich wieder googeln, wie man dies oder das macht. Das Problem stellt sich immer noch heraus, dass Sie das Skript häufig nicht erneut schreiben, sondern das vorhandene Skript ändern, das bereits von jemandem geschrieben wurde. Und es ist vielleicht nicht Bash, sondern Sh oder etwas anderes ... Es gibt Unterschiede in der Syntax, was in Sh funktioniert, sollte in Bash funktionieren, aber nicht immer umgekehrt. Und wenn es Dash oder Asche gibt? Ich weiß nicht ... Es gibt immer noch Unterschiede in diesen Skriptsprachen und sie sind verwirrend. Und natürlich für mich persönlich die Kirsche auf dem Kuchen, wenn das Skript etwas sed oder awk aufruft und es solche Parameter in der Befehlszeile gibt, dass Sie sie betrachten und sich wundern.Es ist klar, dass dies alles von den Qualifikationen des Programmierers abhängt, aber nicht alles passt in meinen Kopf. Und jetzt ist meine Geduld weg und ich dachte, dass ich von nun an versuchen möchte, Skripte in C ++ zu schreiben ...

Ich verstehe, dass mein Gedanke für einen echten Systemadministrator aufrührerisch erscheinen kann. Aber warum nicht?

Die Idee ist also sehr einfach. Ich möchte C ++ - Skripte genauso schreiben wie reguläre Skripte, dh die erste Zeile des Skripts sollte Shebang und einen Hinweis auf den Pfad zum "Interpreter" enthalten:

#!/bin/c++

Die folgenden Zeilen des Skripts sind nur ein reguläres C ++ - Programm.

Ich muss den "Interpreter" des c ++ - Skripts vorbereiten. Sie können es auf alles schreiben, zumindest auf Bash (dies ist das letzte Mal, wenn auch nicht genau). Natürlich wird es kein Interpreter sein, sondern ein Compiler.

Das ist, was ich tat:

#!/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"

Dieses Skript macht alles, was Sie brauchen. Als temporären Ordner habe ich den Ordner ~ / .cache / c ++ gewählt. Das ursprüngliche Skript wird in diesen Ordner kopiert, jedoch ohne die erste Zeile mit shebang. Dies erfolgt über den Befehl tail. Der Name der neuen Datei entspricht dem ursprünglichen Skript, jedoch mit der Erweiterung c ++. Die Binärdatei mit der Erweiterung .bin wird im selben Ordner gesammelt. Aber zuerst wird natürlich zum Zeitpunkt der Erstellung der Binärdatei eine "Wenn-Test" -Prüfung durchgeführt. Die Kompilierung erfolgt nur, wenn die vorhandene Binärdatei in Bezug auf das ursprüngliche „Skript“ zeitlich veraltet ist. Die Binärdatei wird mit dem Befehl eval gestartet und alle Anfangsparameter werden an sie übergeben.

Diese c ++ - Datei muss in den Ordner / bin kopiert und ausführbar gemacht werden (chmod a + x).

Ich werde versuchen, mein erstes "C ++ - Skript" zu schreiben:

#!/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;
}

Dieses Programm druckt einfach eine Liste der Eingabeparameter und gibt deren Nummer + 60 zurück. Ich
führe mein "Skript" aus:



Es funktioniert !!!

Wenn Sie einen Fehler im C ++ - Code machen, wird das Programm nicht gestartet, da es nicht kompiliert wird, sondern $? wird zurückkehren 255. Aber das war es, was beabsichtigt war.

Die Verwendung von c ++ bietet enorme Möglichkeiten. Erstens die bekannte Syntax. Zweitens sind Standardklassen wie std :: vector, std :: map oder std :: string und andere unersetzliche Dinge. Dieselbe Linie - was auch immer Sie damit machen möchten, schauen Sie in die Linie, zerlegen Sie sie in Teilzeichenfolgen, trennen und erobern Sie, erhalten Sie Arrays. Und ich brauche weder sed noch awk. Drittens der Debugger - Gott! was für ein Segen! Ich habe einen GDB-Debugger für das Skript! Außerdem können Sie std :: filesystem verwenden (sofern der Compiler dies zulässt). Du kannst weitermachen ...

Leider passiert es bei mir oft, dass ich es zuerst mache und dann denke ich: "Was ist, wenn jemand dies bereits getan hat?" Und tatsächlich bin ich nicht der erste, der auf die Idee kommt, dasselbe zu tun. Hier ein Beispiel: https://github.com/dimgel/cpp-linux-scripts Die Idee ist dieselbe, die Implementierung ist unterschiedlich. Dann stellte sich heraus, dass es andere Implementierungen gibt .

Im Allgemeinen habe ich eine leichte Enttäuschung über meine eigene Nicht-Exklusivität erfahren. Ich suchte jedoch nach Habr - ich fand keinen ähnlichen. Vielleicht scheint jemand zumindest neugierig?

All Articles