Verwenden von Python zum Analysieren komplexer Argumente für das Shell-Skript

8

Wenn ich Shell-Skripte schreibe, verbringe ich die meiste Zeit (vor allem beim Debuggen) mit der Verarbeitung von Argumenten. Viele Skripte, die ich schreibe oder betreue, sind leicht zu mehr als 80% Eingabe-Parsing und Bereinigung. Ich vergleiche das mit meinen Python-Skripten, wo argparse die meisten Grunt-Arbeiten für mich erledigt und mich leicht konstruieren lässt komplexe Optionsstrukturen und Hygiene- / String-Parsing-Verhalten.

Ich würde daher gerne Python in die Lage versetzen, diese schwere Arbeit zu erledigen, und dann diese vereinfachten und bereinigten Werte in mein Shell-Skript aufnehmen, ohne mich um die Argumente, die der Benutzer angegeben hat, zu kümmern.

>

Um ein konkretes Beispiel zu geben, wurden viele der Shellskripte, in denen ich arbeite, so definiert, dass sie ihre Argumente in einer bestimmten Reihenfolge akzeptieren. Sie können start_server.sh --server myserver --port 80 aufrufen, aber start_server.sh --port 80 --server myserver schlägt mit You must specify a server to start. fehl - es macht den Parsing-Code sehr viel einfacher, aber es ist kaum intuitiv.

Also könnte eine Lösung für den ersten Durchlauf etwas so Einfaches sein, wie Python die Argumente übernehmen, sie sortieren (die Parameter daneben behalten) und die sortierten Argumente zurückgeben. Das Shellskript führt also immer noch eine Parsing- und Bereinigungsfunktion aus, aber der Benutzer kann viel mehr willkürlichen Inhalt eingeben, als das Shellskript nativ akzeptiert, etwa wie folgt:

# script.sh -o -aR --dir /tmp/test --verbose

%Vor%

Hier gibt es einige offensichtliche Einschränkungen, insbesondere dass parse.py nicht zwischen einer abschließenden Option mit einem Argument und dem Beginn der indizierten Argumente unterscheiden kann, aber das scheint nicht so schlimm zu sein.

Hier ist meine Frage: 1) Gibt es ein existierendes (vorzugsweise Python) Dienstprogramm, das CLI-Parsing durch etwas mächtigeres als bash ermöglicht, auf das dann der Rest meines Bash-Skripts zugreifen kann Desinfektion, oder 2) Hat jemand das schon mal gemacht? Gibt es Probleme oder Fallstricke oder bessere Lösungen, die mir nicht bekannt sind? Möchten Sie Ihre Implementierung freigeben?

Eine (sehr unausgegorene) Idee:

%Vor%

Zwei Codezeilen, zusammen mit kurzen Beschreibungen der zu erwartenden Argumente, und wir sind dabei, das eigentliche Skriptverhalten zu sehen. Vielleicht bin ich verrückt, aber das scheint viel schöner zu sein als das, was ich jetzt tun muss.

Ich habe Shell-Skriptargumente analysieren und Dinge wie diese Wiki-Seite auf einfaches CLI-Argumentanalyse , aber viele dieser Muster fühlen sich klobig und fehleranfällig an, und ich mag es nicht, sie jedes Mal neu zu implementieren, wenn ich schreibe ein Shell-Skript, vor allem, wenn Python, Java usw. so nette Bibliotheken zur Argumentverarbeitung haben.

    
dimo414 27.07.2012, 05:05
quelle

3 Antworten

2

Ich habe ein kurzes Python-Skript zusammengestellt, das das meiste von dem macht, was ich will. Ich bin nicht überzeugt, dass es Produktionsqualität ist (vor allem Fehlerbehandlung fehlt), aber es ist besser als nichts. Ich würde jede Rückmeldung begrüßen.

Es nutzt die wunderbare set builtin Weisen Sie die Positionsargumente elegant neu zu, sodass der Rest des Skripts sie weiterhin wie gewünscht behandeln kann.

bashparse.py

%Vor%

Beispielverwendung:

%Vor%

Was, wenn ausgeführt als: ./run.sh one -f 'a_filename.txt' "two' still two" three Folgendes ausgibt (beachten Sie, dass die internen Positionsvariablen immer noch korrekt sind):

%Vor%

Abgesehen von der Debugging-Ausgabe betrachten Sie ungefähr vier Zeilen, um einen leistungsstarken Argumentparser zu erstellen. Gedanken?

    
dimo414 13.08.2012, 22:19
quelle
2

Sie könnten möglicherweise assoziative Arrays in bash nutzen, um Ihr Ziel zu erreichen.

%Vor%

Damit dies funktioniert, sollte getopts.py ein Python-Skript sein, das Ihre Argumente parst und bereinigt. Es sollte eine Zeichenfolge wie die folgende ausgeben:

%Vor%

Sie können Werte reservieren, um zu überprüfen, ob die Optionen auch richtig analysiert und bereinigt werden können.

Zurückgegeben von getopts.py :

%Vor%

Zum Bash-Skript hinzugefügt:

%Vor%

Wenn Sie lieber mit dem Exit-Code von getopts.py arbeiten würden, könnten Sie mit eval :

spielen %Vor%

Alternativ:

%Vor%     
Swiss 27.07.2012 06:01
quelle
2

Da ich genau die gleichen Bedürfnisse hatte, schrieb ich einen optparse-inspirierten Parser für bash (der eigentlich intern Python verwendet); Sie können es hier finden:

Ссылка

Siehe die README unten für eine kurze Erklärung. Sie können ein einfaches Beispiel unter:

ausprobieren

Ссылка

Aus meiner Erfahrung ist es ziemlich robust (ich bin super paranoid), reich an Funktionen usw. und ich benutze es stark in meinen Skripten. Ich hoffe, dass es für andere nützlich sein kann. Feedback / Beiträge willkommen.

    
Carlo Baldassi 19.08.2012 12:15
quelle