Schreiben Sie gelegentlich Shell-Skripte, in denen Sie Benutzereingaben abfragen wollen? Das Tool dialog stellt Ihnen vielfältige Eingabemechanismen zur Verfügung.
out of the box
Es gibt tausende Tools und Utilities für Linux. “out of the box” pickt sich die Rosinen raus und stellt pro Monat ein Progrämmchen vor, das wir für schlichtweg unentbehrlich oder aber zu Unrecht wenig beachtet halten.
Das Programm dialog existiert schon lange als Bestandteil nahezu jeder Linux-Distribution, jedoch fristet es ein unverdientes Schattendasein. Höchstens beim Konfigurieren des Linux-Kernels mit make menuconfig könnte es der Einen oder dem Anderen schon einmal untergekommen sein. Beim “Kernel-dialog” handelt es sich allerdings um eine speziell angepasste und zum normalen Programm inkompatible Version.
Den Dialog suchen
Seit kurzem hat das Programm eine eigene Homepage unter der URLhttp://www.advancedresearch.org/dialog/. Der aktuelle dialog-Maintainer Vincent Stemen hat diese Seite erstellt, während sich der ursprüngliche Autor Savio Lam mittlerweile anderen Projekten widmet. Falls das Programm noch nicht auf Ihrem Rechner installiert ist, bekommen Sie auf dieser Web-Seite oder von der Heft-CD ein Quellen-Archiv.
Ob Sie nachinstallieren müssen, erfahren Sie mit dem Kommando which dialog. Liefert es keine Ausgabe, so ist dialog nicht installiert. Lautet die Ausschrift dagegen /usr/bin/dialog, finden Sie das Programm im Verzeichnis /usr/bin.
Installation
Mit yast(2), rpm, dpkg, apt-get und Co. können Sie dialog selbstverständlich auch als Ihrer Distribution beiliegendes rpm– oder deb-Paket installieren. Falls Sie das Programm stattdessen selbst kompilieren wollen, gehen Sie folgendermaßen vor:
tar xzf dialog-0.7.tar.gz cd dialog-0.7 make chmod 755 dialog chmod 644 dialog.1 su (root-Passwort eingeben) cp dialog /usr/local/bin cp dialog.1 /usr/local/man/man1 exit
Die beiden Rechteänderungen mit dem Kommando chmod sind nötig, da standardmäßig auch die Gruppe, der die Datei gehört, Schreibrechte bekommt.
Ja oder nein
Für einen kurzen Test geben Sie das Kommando dialog --yesno "Spielen Sie ein Instrument?" 15 60 ein. Es sollte eine Box von 60 Zeichen Breite und 15 Zeilen Höhe mit dem Fragetext und zwei Buttons Yes und No erscheinen (Abbildung 2). Mit den Cursor-Tasten und [Tab] schalten Sie zwischen den Knöpfen hin und her, mit [Return] bestätigen Sie die Auswahl. Außerdem lassen sich die Buttons direkt durch die hervorgehobenen Buchstaben [y] und [n] anwählen. Auch ohne Auswahl können Sie die Box verlassen; dazu drücken Sie [Esc].
dialog gibt die von Ihnen getroffene Auswahl in der speziellen Shell-Variablen namens ? zurück. Diese Variable – abfragbar mit echo $? – enthält grundsätzlich den numerischen Rückgabewert des letzten Shell-Kommandos. Im Fall der yesno-Box bedeutet 0 ja, 1 nein und 255 Abbruch ohne Auswahl.
Eingebettet
Um dialog sinnvoll einzusetzen, bettet man es in ein Shell-Skript ein, das abhängig vom Rückgabewert verschiedene Dinge tut. Listing 1 gibt ein Beispiel.
Listing 1
Shell-Skript mit Dialog
#!/bin/sh
dialog --backtitle Quiz --title Musikfrage \
--yesno "Spielen Sie ein Instrument?" 15 60
ans=$?
if [ $ans = 255 ] ; then
echo Abgebrochen
exit
fi
if [ $ans = 1 ] ; then
dialog --backtitle Quiz --title Aufforderung \
--msgbox "Na dann lernen Sie doch mal eins!" 15 40
exit 0
else
dialog --backtitle Quiz --title Details \
--radiolist "Welches Instrument spielen Sie? \
Sie können nur eins wählen." 16 60 5 \
"Geige" "(Streichinstrument)" off \
"Gitarre" "(Saiteninstument)" on \
"Klavier" "(Tasteninstument)" off \
"Trompete" "(Blasinstument)" off \
"Bass" "(Saiteninstument)" off 2> /tmp/dialog.sel
instr=$(cat /tmp/dialog.sel)
rm /tmp/dialog.sel
if [ -z $instr ] ; then
echo Abgebrochen
exit
fi
dialog --backtitle Quiz --title "Quiz beendet" \
--msgbox "Sie spielen also $instr. Dann lassen Sie mal \
hören… klingt ja grauenvoll! ;-)" 16 40
fi
Eine Reihe weiterer Optionen ist hier dazu gekommen. So bekommen die jeweiligen Boxen mit --backtitle und --title vernünftige Überschriften verpasst. Der Rückgabewert der ersten Box wird in der Variablen ans gespeichert und mit if-Konstrukten ausgewertet. Die Option --msgbox veranlasst dialog, eine einfache Nachricht ohne Wahlmöglichkeit darzustellen. Das Flag --radiolist stellt hingegen eine Liste dar, von der nur ein Element mit der Leertaste wählbar ist (Abbildung 3), ähnlich den Stationstasten bei einem Radio (daher der Name der Option).
Die Auswahl eines Radiolisten-Elements wird nicht numerisch zurückgegeben, sondern als Text auf dem Standardfehlerkanal (stderr). Entsprechend muss dieser zum Zwischenspeichern in eine temporäre Datei umgeleitet werden – dies geschieht mit dem Konstrukt 2> /tmp/dialog.sel. Der Inhalt dieser Datei wird in die Variable instr geschrieben. Ist diese leer (dies wird mit -z geprüft), wurde die Auswahl mit Cancel oder [Esc] abgebrochen. Andernfalls wird ihr Inhalt in einer weiteren msgbox dargestellt und das Skript beendet.
Was darf’s denn sein?
Eine relativ neue Option in dialog ist --file. Damit steht eine komfortable Dateiauswahl zur Verfügung. Das Shell-Skript in Listing 2 zeigt ein Anwendungsbeispiel, das jedoch nur mit einem neuen dialog, nicht mit der auf aktuellen Distributionen installierten Version 0.62 oder älter lauffähig ist.
Es zeigt einen Dateiauswahldialog, mit dem man ausgehend vom eigenen Home-Verzeichnis durchs Dateisystem brausen kann. Schließt man den Dialog durch Auswahl des OK-Buttons, erhält man Zeichen- und Zeilenzahl der letztgewählten Datei angezeigt.
Listing 2
Dateiauswahl mit Dialog
#!/bin/sh
dialog --backtitle "Textdatei öffnen" \
--title "Dateiauswahl" --clear \
--file $HOME 15 62 0 2>/tmp/dialog.file
file=$(cat /tmp/dialog.file)
rm /tmp/dialog.file
if [ ! -z $file ] ; then
echo $file enthält $(wc -l < $file) Zeilen und \
$(wc -c < $file) Zeichen.
fi
Der Option --file folgt das Startverzeichnis für die Dateiauswahl (in diesem Fall das Home-Verzeichnis des aktuellen Benutzers, das in der Umgebungsvariablen HOME gespeichert ist). Die nächsten beiden Werte bestimmen die Höhe (15) und Breite (62) der Box. Der nachfolgende Wert gibt den Modus für die Box an, mögliche Modi führt Tabelle 1 auf. Die Auswahl einer existierenden Datei (Modus 0) ist in Abbildung 4 dargestellt.
Ähnlich wie im vorigen Beispiel wird der Rückgabewert zunächst in eine temporäre Datei gespeichert und in die Variable file eingelesen. Ist diese Variable nicht leer (wird mit ! -z geprüft), so gibt das Skript unter Verwendung des Kommandos wc die Zeilen- und Zeichenzahl der gewählten Datei aus.
Tabelle 1: Modi für –file
| Modus | Bedeutung |
|---|---|
| 0 | Auswahl einer existierenden Datei |
| 1 | Auswahl eines existierenden Verzeichnisses |
| 2 | Eingabe eines existierenden oder nicht existierenden Verzeichnisses |
| 3 | Eingabe einer existierenden oder nicht existierenden Datei |
RTFM
dialog lässt sich auch als einfacher Pager zum Lesen von Textdateien gebrauchen. Hierzu verwenden Sie die Option --textbox. Um beispielsweise die Datei /etc/services zu lesen, geben Sie in der Shell dialog --title /etc/services --textbox /etc/services 18 70 ein. Zur Navigation im Text stehen die Cursor-Tasten, [Bild hoch],[Bild runter] und die Leertaste zur Verfügung. Mit [/] und [?] können Sie vorwärts bzw. rückwärts suchen.
Hinweise zu weiteren nützlichen dialog-Optionen wie Checklisten oder Eingabefeldern finden sich in der Manpage, die Sie mit man dialog aufrufen.
Kasten 1: Shell-Skripting
Für alle, die bisher noch nicht mit Shell-Skripten zu tun hatten, ein paar Erklärungen zu den Listings in diesem Artikel. Shell-Skripte sind Textdateien mit Folgen von Kommandos, die von der Shell nach dem Aufruf der Datei nacheinander abgearbeitet werden. Sie können die Abarbeitung auch an Bedingungen knüpfen (if-Kommando) oder Teile des Skripts wiederholen lassen (while– und for-Kommandos).
Zum Zwischenspeichern von Werten sind Variablen nützlich, die einfach dadurch entstehen, dass man einen Namen hinschreibt und ihm hinter einem Gleichheitszeichen einen Wert zuweist. An den Inhalt einer Variablen kommt man heran, indem man dem Variablennamen ein $ voranstellt.
Bei if-Konstrukten wird die eigentliche Bedingung oft mit dem Kommando test formuliert, das sich auch abgekürzt [ schreiben lässt. Einfache Vergleiche sind mit = möglich, aber auch Datei- und Zeichenkettenprüfungen werden durch Optionen zur Verfügung gestellt. So testet [ -f foo ], ob foo eine reguläre Datei ist; [ -z $bar ] prüft, ob der Inhalt der Variablen bar leer ist, und [ $a -gt $b ] sieht nach, ob der Inhalt von a (als Zahl interpretiert) größer als (“greater than”) der von b ist.
Eine if-Abfrage muss für die Shell immer mit einem fi abgeschlossen werden. Dazwischen darf auch ein else-Zweig stehen, in dem alternative Bearbeitungsmöglichkeiten angegeben werden, die dann zum Zug kommen, wenn die if-Bedingung nicht erfüllt ist.
Die Schreibweise bla=$(kommando) führt zuerst das Kommando in der Klammer aus und setzt dessen Ausgabe dann an dieser Stelle in die restliche Kommandozeile ein, so dass die Ausgabe der Variablen bla zugewiesen wird. Dieser Mechanismus wird Kommandosubstitution genannt.
Um überlange Zeilen in Shell-Skripten lesbarer zu machen, können Sie vor das Zeilenende einen Backslash (\) schreiben. Damit weiß die Shell, dass die nächste Zeile als Fortsetzung der aktuellen anzusehen ist.
Sollen auf einer Zeile hingegen mehrere Kommandos abgesetzt werden, muss man sie mit Semikola voneinander trennen. Dies ist zum Beispiel nach einem if-Test der Fall. Stünde das darauf folgende Schlüsselwort then auf einer eigenen Zeile, wäre kein Semikolon nötig.
Außer der Standardausgabe und dem Standardfehlerausgabe, die normalerweise auf dem Bildschirm landen und mit > bzw. 2> in eine Datei umgeleitet werden können, kennt die Shell auch noch den Standardeingabekanal. Dieser ist normalerweise mit der Tastatur verknüpft, aber ein
Kommando < Datei
sorgt dafür, dass das Kommando die Daten bearbeitet, die in Datei stehen. Auf diese Art und Weise erhält das Kommando wc in Listing 2 die zu zählenden Zeilen und Zeichen aus dem in der Variablen file abgelegten Inhalt. (Christian Perle/Patricia Jung)
Glossar
-
Kernel
-
Der Betriebssystemkern bildet die Schnittstelle zwischen Hardware und laufenden Prozessen. Außerdem stellt er Multitasking und Speichermanagement zur Verfügung. Das eigentliche Linux ist nur der Kernel.
-
URL
-
“Uniform Resource Locator”, die eindeutige Adresse einer Ressource im Netz. In der URL ist auch das Übertragungsprotokoll angegeben, z. B. http://www.linux.de/links/Distributionen/ oder ftp://ftp.gwdg.de/linux/mirrors/.
-
rpm
-
Mit dem “Red Hat Packet Manager” (den u. a. auch SuSE einsetzt) können Softwarepakete sauber installiert und deinstalliert werden. Das zugehörige Paketformat heißt ebenfalls RPM.
-
deb
-
Das Paketformat der Debian-Distribution. Mit dem Paketmanager dpkg oder dem komfortableren Frontend apt lassen sich solche Pakete bequem installieren und deinstallieren.
-
Shell
-
Einer der wichtigsten Bestandteile jedes Unix-Systems – die kommandozeilengesteuerte Benutzerschnittstelle.
-
$
-
Um den Inhalt einer Shell-Variablen herauszufinden, stellt man den Operator $ vor den Variablennamen.
-
RTFM
-
“Read The Fine Manual”, der dezente Hinweis darauf, dass eine Dokumentation zum Durchlesen da ist.
-
Pager
-
Programm zum seitenweisen Anzeigen einer Datei. Verbreitete Pager sind more und less.









