42.4 Kommandozeilen-Interpreter 

Das Modul cmd bietet eine einfache und abstrahierte Schnittstelle zum Schreiben eines zeilenorientierten Kommando-Interpreters – cmd. Unter einem zeilenorientierten Kommando-Interpreter versteht man eine interaktive Konsole, in der zeilenweise Kommandos eingegeben und direkt nach Bestätigung der Eingabe interpretiert werden. Der interaktive Modus ist ein bekanntes Beispiel für solch einen Kommando-Interpreter. In einem eigenen Projekt ließe sich cmd beispielsweise für eine Administratorkonsole verwenden.
Das Modul cmd enthält die Klasse Cmd, die als Basisklasse für eigene Kommando-Interpreter verwendet werden kann und dafür ein grobes Gerüst bereitstellt. Da Cmd als Basisklasse gedacht ist, ergibt es keinen Sinn, die Klasse direkt zu instanziieren. Das folgende Beispielprojekt verwendet die Klasse Cmd, um eine rudimentäre Konsole zu erstellen. Die Konsole soll die beiden Kommandos date und time verstehen und jeweils das aktuelle Datum bzw. die aktuelle Uhrzeit ausgeben.
import cmd
import time
class MeineKonsole(cmd.Cmd):
def __init__(self):
super().__init__()
self.prompt = "==> "
def do_date(self, prm):
d = time.localtime()
print("Heute ist der {:02}.{:02}.{:02}".format(d[2],d[1],d[0]))
return False
def help_date(self):
print("Gibt das aktuelle Datum aus")
def do_time(self, prm):
z = time.localtime()
print("Es ist {:02}:{:02}:{:02} Uhr".format(z[3], z[4], z[5]))
return False
def do_timer(self, prm):
if prm == "start":
self.startTime = time.perf_counter()
elif prm == "get":
print("Es sind {} Sekunden vergangen.".format(
int(time.perf_counter() - self.startTime)))
def do_exit(self, prm):
print("Auf Wiedersehen")
return True
Im Beispiel wurde die Klasse MeineKonsole definiert, die von cmd.Cmd abgeleitet ist. Im Konstruktor der Klasse wird die Basisklasse initialisiert und das Attribut self.prompt gesetzt. Dieses Attribut stammt von der Basisklasse und referenziert den String, der zur Eingabe eines Kommandos auffordern soll.
Unsere Konsole soll insgesamt vier Kommandos unterstützen: date zum Ausgeben des aktuellen Datums, time zum Ausgeben der aktuellen Uhrzeit, timer zum Initialisieren und Auslesen einer Stoppuhr und exit zum Beenden der Konsole. Um ein Kommando in einer cmd.Cmd-Konsole zu implementieren, wird einfach eine Methode do_kommando angelegt, wobei kommando durch den Namen des jeweiligen Kommandos ersetzt werden muss. In diesem Sinne finden Sie in der Klasse MeineKonsole die Methoden do_date, do_time, do_timer und do_exit für die drei verfügbaren Kommandos. Jede dieser Methoden wird aufgerufen, wenn das Kommando vom Benutzer eingegeben wurde, und bekommt als einzigen Parameter prm den String übergeben, den der Benutzer hinter das Kommando geschrieben hat. Die Beispiel-Implementation der Methoden ist denkbar einfach und braucht an dieser Stelle nicht näher erläutert zu werden.
Wichtig ist, dass eine Kommandomethode anhand des Rückgabewertes angibt, ob die Konsole nach diesem Kommando noch weitere Kommandos annehmen soll. Wenn die Methode False zurückgibt, werden weitere Kommandos entgegengenommen. Bei einem Rückgabewert von True wird die Kommandoschleife beendet. Der Rückgabewert False einiger Methoden ist im oben dargestellten Beispiel überflüssig, da eine Funktion oder Methode ohne Rückgabewert implizit None zurückgibt und der Wahrheitswert von None False ist. Dennoch ist die entsprechende return-Anweisung zu Demonstrationszwecken im Quellcode enthalten.
Zusätzlich zu den Kommandomethoden existiert eine Methode help_date als Beispiel-Implementation der interaktiven Hilfe, die die Klasse cmd.Cmd bereitstellt. Wenn der Benutzer ein Fragezeichen oder den Befehl help eingibt, gefolgt von einem Kommandonamen, wird die Methode help_kommando mit dem entsprechenden Kommandonamen aufgerufen. Diese gibt dann einen kurzen erklärenden Text zu dem jeweiligen Kommando aus.
Um den oben dargestellten Code zu einem vollwertigen Programm zu ergänzen, muss die Klasse instanziiert und die Kommandoschleife durch Aufruf der Methode cmdloop gestartet werden:
konsole = MeineKonsole()
konsole.cmdloop()
Nach dem Starten des Programms wird der Benutzer durch Ausgabe des Prompts ==> dazu aufgefordert, ein Kommando einzugeben. Eine Beispielsitzung in unserer Konsole sieht folgendermaßen aus:
==> date
Heute ist der 10.03.2017
==> time
Es ist 19:26:50 Uhr
==> time
Es ist 19:26:54 Uhr
==> timer start
==> timer get
Es sind 5 Sekunden vergangen.
==> exit
Auf Wiedersehen
Die Hilfetexte der Kommandos können folgendermaßen angezeigt werden:
==> help date
Gibt das aktuelle Datum aus
==> ? date
Gibt das aktuelle Datum aus
==> help
Documented commands (type help <topic>):
========================================
date
Undocumented commands:
======================
exit help time
Der Befehl help ohne Parameter gibt eine Liste aller dokumentierten und undokumentierten Kommandos Ihrer Konsole aus.
Das hier vorgestellte Beispielprogramm versteht sich als eine einfache Möglichkeit, die Klasse Cmd zu verwenden. Neben der hier gezeigten Funktion bietet die Klasse weitere Möglichkeiten, um das Verhalten der Konsole genau an Ihre Bedürfnisse anzupassen.