AA_wizard_fernando-gregory-milan_123rf_44405606.jpg

© Fernando Gregory Milan, 123RF

Mit Docopt Optionen für die Kommandozeile auswerten

Zauberlehrling

,
Es macht viel Arbeit, beim Erstellen von Programmen Optionen für die Kommandozeile zu definieren und zu parsen. Docopt senkt dabei den Aufwand.

Computerprogramme dienen immer einem bestimmten Zweck. Die Werkzeuge auf Linux-Systemen fallen dabei oft sehr spezialisiert aus und folgen der Idee, nur eine einzige Aufgabe zu erledigen, die aber so gut wie möglich [1]. Diese einzelnen Tools kombinieren Sie bei Bedarf miteinander zu mächtigen Ketten [2]. Mithilfe von Optionen, die Sie den Programmen beim Aufruf mitgeben, steuern Sie den Verlauf und fangen Sonderfälle ab (siehe Kasten "Nachgesteuert").

Nachgesteuert

Das Konzept der Optionen ermöglicht es, Programmfunktionen über den Aufruf anzusteuern, etwa um zusätzliche Informationen auszugeben, Daten von einer bestimmten Quelle zu lesen oder in einem gewünschten Format zu interpretieren und zu verarbeiten. Programme erwarten diese Optionen je nach Plattform in unterschiedlicher Notation: Auf Unix-Systemen beginnen sie in der Regel mit einem Minus, gefolgt von einem Einzelbuchstaben, wie -h. Auf Systemen, die auf die GNU-Tools setzen, kommen Lang-Optionen hinzu. Sie beginnen mit einem doppelten Minus, gefolgt von einem Wort, wie --help. Unter Microsoft Windows leitet man Optionen dagegen mit einem Schrägstrich ein, gefolgt von einem Buchstaben oder einem Wort, wie /help.

Diese drei Ansätze existieren aus historischen Gründen. Viele Programme auf unixoiden Systemen unterstützen entweder den Unix-Weg [7], den GNU-Weg [8] oder beides. Die Unix-Notation ist kürzer, die GNU-Version lässt sich oft leichter lesen. Versuche, beide Schreibweisen in einem einheitlichen Schema zu vereinigen, waren bislang nicht von Erfolg gekrönt. Zudem gilt es, stets im Kopf zu behalten, dass sowohl die Schreibweise als auch die Bedeutung der Option spezifisch für das jeweilige Programm sind. Werfen Sie daher stets einen Blick in die Manpage, um sicherzugehen, wofür eine Option steht und was sie tatsächlich bewirkt. Allerdings folgen Entwickler häufig Konventionen: So stehen -h, --help und /h in der Regel für die Hilfe oder Zusatzinformationen zum Werkzeug.

Als Entwickler entscheiden Sie, welche Optionen im Programm gelten. Das erfordert nicht nur eine korrekte Definition, sondern auch eine saubere Auswertung durch die Software. Die Tabelle "Auswertung" stellt verschiedene Varianten dazu gegenüber. Befürworter von Python nutzen die Methode sys.argv() oder greifen auf eines der drei Module getopt, argparse oder optparse [3] zurück.

Auswertung

Implementierung C/C++ Python Perl Tcl
Sprachstandard argc(), argv() sys.argv() @ARGV $argc, $argv
Getopt getopt() getopt Getopt commandline::getopt
Argparse argp() argparse Getopt::argparse
Optparse optparse optparse
Docopt docopt docopt docopt docopt::docopt
GetKnownOpt commandline::getKnownopt
Usage commandline::usage
Suboptions suboptions

Mit Docopt [4] erweitert sich der Spielraum demgegenüber erheblich. Damit drehen Sie sozusagen den Spieß in der Entwicklung um: Sie erzeugen zunächst eine Beschreibung, aus der Sie dann die einzelnen Optionen bestimmen. Der Ansatz ähnelt jenem von Literate Programming, wo Sie eine Beschreibung formulieren und daraus dann den Code des Programms erzeugen, Dokumentation inklusive [5].

Docopt entstammt ursprünglich der Python-Welt. Inzwischen haben die Entwickler weitere Programmiersprachen integriert, darunter C++, F#, Go und Ruby. Unter Debian und Ubuntu heißen die zugehörigen Pakete python-docopt beziehungsweise python3-docopt (für Python 3). Alle Beispiele hier im Beitrag nutzen Python 3. Sofern noch nicht vorhanden, installieren Sie eines der Pakete über die Paketverwaltung nach.

Docopt sieht sich selbst als "Command-line interface description language". Ein Parser wertet die Beschreibung aus. Diese basiert auf den Gepflogenheiten zur Schreibweise für Hilfetexte und Handbuchseiten, wie sie seit Jahrzehnten unter Linux-Systemen üblich sind.

Alles zusammentragen

Docopt greift auf ein Konzept zurück, das Docstring heißt und so viel wie Angabe zur Dokumentation bedeutet. Am Anfang eines Python-Programms, einer Funktion oder Methode erfolgt eine Beschreibung der Parameter, die das Programm beziehungsweise der Block-Code akzeptiert [6]. Zur Dokumentation des Codes empfiehlt es sich ohnehin, das zu tun – warum also nicht doppelten Nutzen daraus ziehen?

Listing 1 zeigt, wie Sie das nutzen. Die Zeilen 3 bis 10 beschreiben den Aufruf in Form eines Hilfetexts auf einer Manpage. Diese Angaben erlauben noch weitere Möglichkeiten. Aus der Beschreibung ersehen Sie, dass Sie das Programm helloworld.py entweder ganz ohne Parameter oder mit den Schaltern --help beziehungsweise --verbose aufrufen.

Listing 1

#!/usr/bin/python
"""Usage:
  ./helloworld.py
  ./helloworld.py --help
  ./helloworld.py --verbose
 Options:
  --help     display help information
  --verbose  increase the verbosity of output
"""
# include docopt module
from docopt import docopt
if __name__ == '__main__':
  arguments = docopt(__doc__)
  print (arguments)
  if arguments["--verbose"]:
    print("enabling verbose output")

Zeile 14 bindet das Modul docopt ins Programm ein. Das Auswerten der erlaubten Parameter erfolgt in Zeile 17. Dazu greift der Parser aus der Docopt-Klasse auf den Docstring aus den Zeilen 3 bis 10 zurück, die Python über die interne Variable __doc__ zugänglich macht.

Als Ergebnis liefert der Aufruf eine Liste der Parameter, die das Skript in Zeile 18 ausgibt. Sofern Sie keinen Wert für den Schalter angeben, merkt sich Docopt als Wert True oder FalseTrue, wenn Sie den Parameter im Aufruf angegeben haben. Das nutzen Sie dann in Zeile 20 aus.

Abbildung 1 zeigt drei Aufrufe des kleinen Programms – einmal ohne Option, einmal mit --verbose und schließlich mit --help. Letzteres gibt den gesamten Docstring aus und ist bereits vordefiniert. Geben Sie eine Option an, die Sie nicht im Abschnitt mit der Dokumentation definiert haben, gibt das Programm alle Zeilen von dort bis zur ersten Leerzeile aus – in unserem Beispiel also die Zeilen 3 bis 6.

Abbildung 1: Ein einfaches Skript demonstriert, wie Sie die Dokumentation der Optionen direkt im Programmcode unterbringen.

Zweiter Streich

Hier bleibt noch Raum für Verbesserungen – etwa lange und kurze Parameter. Es genügt dazu, den Hilfetext anzupassen. Listing 2 ergänzt -v zu --verbose und -h zu --help. Die Schreibweise mit den eckigen Klammern und der Pipe in den Zeilen 5 und 6 des Docstrings bedeutet entweder/oder. Für den Aufruf ist es ab jetzt unerheblich, welchen Stil für die Optionen Sie bevorzugen – es funktioniert beides.

Listing 2

"""Usage:
  ./helloworld.py
  ./helloworld.py [--help | -h]
  ./helloworld.py [--verbose | -v]
 Options:
  --help -h     display help information
  --verbose -v  increase the verbosity of output
"""

Doch es gibt zwei Stolperfallen, eine davon beim Auswerten der Parameter im Programm. Existiert für eine lange Option zusätzlich eine kurze Version, schreiben Sie nur eine Abfrage für die lange Version – Docopt wertet die kurze Variante dann automatisch mit aus. Eine zusätzliche Abfrage für den kurzen Parameter löst bislang eine Fehlermeldung aus.

Die zweite Falle besteht bei der Angabe der Optionen im Docstring. Geben Sie zuerst die lange Version an und danach die kurze, trennen Sie beide Werte mit einem Leerzeichen. Gehen Sie umgekehrt vor, müssen Sie beide Werte stattdessen mit einem Komma trennen (Listing 3).

Listing 3

Options:
 -h, --help    display help information
 --verbose -v  increase the verbosity of output

Es empfiehlt sich, im Docstring mindestens zwei Leerzeichen zwischen die Option und den Beschreibungstext zu setzen. Damit signalisieren Sie dem Parser, dass keine weitere Option folgt, sondern eine Erläuterung (Listing 4).

Listing 4

Options:
 --left -l  nach links  # gut
 --right -r nach rechts # schlecht

Positional Arguments kennzeichnen Sie in Form von Worten in Kleinbuchstaben, die Sie mit spitzen Klammern einschließen (Listing 5). Docopt akzeptiert das Wort aber selbst dann, wenn Sie es vollständig in Großbuchstaben schreiben.

Listing 5

"""Usage:
  ping <host> PORT
"""

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 5 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

LinuxCommunity kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Check inklusive
    Wer mit Python programmiert, bekommt mit dem Doctest-Modul eine einfache Möglichkeit, die Programmfunktionen anschaulich zu dokumentieren und gleichzeitig zu testen.
  • Funktionen, Module und Pakete in Python
    Gliedern Sie Ihre Python-Programme in Funktionen, Module und Pakete. Python bietet Ihnen ebenfalls einige davon.
  • Entwicklungshelfer
    Nachdem in den ersten Teilen der Python-Einführung die Sprache beschrieben wurde, geht es im letzten Teil um nützliche Hilfen rund um Python.
  • Bash-Konfiguration, die zweite
    In diesem zweiten Teil der Serie über die Konfiguration der Bash wird es noch einmal praktisch: Das Einstellen des Prompts, und die für die Fehlersuche so nützlichen Tracing-Modi werden beschrieben.
  • Shell-Tipps
    Unter Linux werden wie in jedem Betriebssystem immer wieder Dateien und Verzeichnisse gelöscht. Normalerweise treten dabei keine Probleme auf. Es gibt aber einige Besonderheiten, über die sich ein Anwender im Klaren sein sollte. Einige Problemfälle und mögliche Lösungen werden hier kurz vorgestellt.
Kommentare

Infos zur Publikation

LU 02/2018: PAKETE VERWALTEN

Digitale Ausgabe: Preis € 5,95
(inkl. 19% MwSt.)

LinuxUser erscheint monatlich und kostet 5,95 Euro (mit DVD 8,50 Euro). Weitere Infos zum Heft finden Sie auf der Homepage.

Das Jahresabo kostet ab 86,70 Euro. Details dazu finden Sie im Computec-Shop. Im Probeabo erhalten Sie zudem drei Ausgaben zum reduzierten Preis.

Bei Google Play finden Sie digitale Ausgaben für Tablet & Smartphone.

HINWEIS ZU PAYPAL: Die Zahlung ist ohne eigenes Paypal-Konto ganz einfach per Kreditkarte oder Lastschrift möglich!

Stellenmarkt

Aktuelle Fragen

JQuery-Script läuft nicht mit Linux-Browsern
Stefan Jahn, 16.02.2018 12:49, 2 Antworten
Hallo zusammen, ...folgender goldener Code (ein jQuery-Script als Ergebnis verschiedener Exper...
XSane-Fotokopie druckt nicht mehr
Wimpy *, 30.01.2018 13:29, 0 Antworten
openSuse 42.3 KDE 5.8.7 Seit einem Software-Update druckt XSane keine Fotokopie mehr aus. Fehler...
TOR-Browser stürzt wegen Wikipedia ab
Wimpy *, 27.01.2018 14:57, 0 Antworten
Tor-Browser 7.5 based on Mozilla Firefox 52.8.0 64-Bit. Bei Aufruf von http: oder https://de.wi...
Wifikarte verhindert Bootvorgang
Maik Kühn, 21.01.2018 22:23, 1 Antworten
iwlwifi-7265D -26 failed to load iwlwifi-7265D -25 failed to load iwlwifi-7265D -24 failed to l...
sharklinux
Gerd-Peter Behrendt, 18.01.2018 23:58, 2 Antworten
Hallo zusammen, ich habe sharklinux von der DVD Installiert. 2x, jedesmal nach dem Reboot ist di...