Soll ein Shellskript mit seinen Benutzern interagieren, braucht der zuständige Bash-Programmierer auf den Spatz nicht gleich mit der GUI-Toolkit-Kanone samt zusätzlicher Programmiersprache zu schießen. Wie das Kleinkaliber funktioniert, beschreibt dieser Artikel.
Unter [1] findet sich ein praktisches Skript für Wartungsarbeiten an WordPress-Datenbanken, seine ersten Zeilen zeigt Listing 1. Für den Datenbankzugriff braucht das Skript das zugehörige Passwort – der Programmierer hat sich offenbar der Einfachheit halber dazu entschlossen, dass der Benutzer es dem Skript als Parameter übergibt.
Mal abgesehen davon, dass das ganze Parameter-Handling nicht besonders robust gelöst ist, stellt die Übergabe von Passwörtern auf der Kommandozeile ein Sicherheitsrisiko dar. Denn jeder Benutzer kann die Prozessliste mit allen Parametern auslesen. Um diesen Designfehler zu vermeiden, muss das Skript selbst den Benutzer nach dem Datenbank-Passwort fragen, dessen Antwort entgegennehmen und verarbeiten.
Listing 1
wordpress-cleanup
01 #! /bin/bash 02 03 # Korrekte Parameteranzahl überprüfen 04 if [ $# -ne 4 ]; 05 then 06 echo "Usage: wordpress-cleanup <Database> <Table-Prefix> <Username> <Password>" 07 exit 0 08 fi 09 10 # Variablen deklarieren 11 DATABASE=$1 12 WPPREFIX=$2 13 USERNAME=$3 14 PASSWORD=$4 15 16 # MySQL-Queries ausführen 17 mysql -u$USERNAME -p$PASSWORD $DATABASE <<EOF 18 [...]
Es kann kaum überraschen, dass die Bash auch für dieses Problem eine Lösung parat hält. Die Passwortabfrage ist aber nur ein Spezialfall für die Benutzereingabe einzeiliger Texte. Die Bash hat dafür den Befehl »read« und neuerdings »readarray« eingebaut. In Listing 2 verhindert die »read« -Option »-r« (für raw), dass ein Backslash als Escape-Zeichen wirkt. Die Option »-e« weist den Befehl an, die Readline-Bibliothek zu nutzen – der Anwender darf Bash-typisch in der Zeile navigieren.
Die Zeile 2 im Listing ist die klassische Passwortabfrage mit der »-s« -Option (für silent). Bei der letzten Variante führt »”-N 1″« dazu, dass der Anwender nur einen Buchstaben eingeben muss. Aus GUI-Sicht handelt es eher um eine Messagebox als um ein Eingabefeld.
Die Beispiele haben jeweils als letztes Argument nur eine Variable. Fehlt sie, schreibt Read den eingegebenen Wert in die Variable »REPLY« . Bei mehr als einer Variablen parst der Read-Befehl die Antwort. Read kennt noch ein paar Optionen mehr, die Manpage zur Bash gibt darüber ausreichend Auskunft.
Listing 2
Eingabefeld mit Bash-Mitteln
01 read -r -e -p "Bitte Wert eingeben: " zeile 02 read -p "Passwort: " -s passw 03 read -p "Sind Sie sicher? J/N: " -N 1 antwort
Längere Texte erfassen
Im manchen Fällen ist eine Zeile Eingabetext aber zu wenig. Wer längere Texte abfragen will, startet einfach einen Editor. Per Konvention steht der bevorzugte Editor in der Variablen »EDITOR« . Ist diese nicht gesetzt, dann ist der Vi die sicherste Wahl. Mit Bash-Mitteln gelingt es aber auch:
echo "Eingabe mit Strg-D beenden:" textFeld="$(</dev/stdin)"
Die Anführungszeichen sind wichtig, ansonsten ersetzt die Bash die Zeilenumbrüche durch Leerzeichen. Diese Form ist sehr einfach und kompakt, verschafft dem Anwender aber keine Gelegenheit, im geschriebenen Text zu navigieren und Korrekturen durchzuführen.
Menüs und Auswahllisten
Menüs und Auswahllisten zaubert der Bash-Befehl »select« auf den Bildschirm. Ein Beispiel zeigt Listing 3. Es beschreibt einen einfachen Logfile-Browser, bei dem der Benutzer die gewünschte Datei nicht erst über »ls« suchen muss, sondern das Skript bietet ihm eine Liste zum Auswählen an. Der Befehl »select name in …« führt alle Wörter in der »in« -Liste als einzelne Listenpunkte auf und gibt daraufhin den PS3-Prompt aus. Das Beispiel setzt den Prompt in Zeile 3. Jetzt kann der Benutzer eine der vordefinierten Nummern eingeben, aber auch andere Antworten sind möglich.
Nur im ersten Fall landet der Wert der ausgewählten Nummer in der »select« -Variablen. Bei falscher Eingabe ist die Variable leer. Die eigentliche Eingabe des Anwenders, also die Nummer oder sonstiger eingegebener Text, landet immer in der Shellvariablen »REPLY« . Mit einem Dateiende-Zeichen ([Strg]+[D]) beendet der Benutzer die Auswahl.
Listing 3
Auswahlliste per select
01 #!/bin/bash 02 03 PS3="Auswahl der Log-Datei: " 04 select logfile in /var/log/messages* quit; do 05 echo -e "Log-Datei: $logfile\nAuswahl: $REPLY" 06 if [ -n "$logfile" ]; then 07 case "$logfile" in 08 quit) exit 0;; 09 *) less "$logfile";; 10 esac 11 elif [ "$REPLY" = "quit" -o "$REPLY" = "q" ]; then 12 exit 0 13 else 14 echo "Fehlerhafte Eingabe!" >&2 15 fi 16 done
Bestenliste
Als benutzerfreundlicher erweist sich das Anwendungspattern aus Listing 3. Zusätzlich zu den Dateinamen (»/var/log/messages*« ) steht der feste Wert »quit« in der »in« -Liste. Außerdem prüft das Programm bei einer falschen Eingabe, ob der Benutzer statt der Nummer irrtümlich »quit« oder zumindest »q« eingegeben hat (siehe Abbildung 1).

Listing 3 präsentiert eine Liste zum Auswählen einer Logdatei.” width=”300″ height=”102″ />
Abbildung 1: Das gestartete Skript aus Listing 3 präsentiert eine Liste zum Auswählen einer Logdatei.Auf die Anordnung der Liste hat der Programmierer keinen Einfluss. Wer eine spezielle Anordnung will oder statt der Nummern Buchstaben, muss das Menü selbst programmieren. Im Prinzip ist das aber nicht aufwändig: Eine »while true; do … done« -Schleife erfüllt den Zweck. Zuerst gibt das Programm per »echo« das Menü aus, anschließend liest es mit »read« die Antwort.
In einem alten, inzwischen von modernerer Software überholten Projekt des Autors kam diese Lösung zum Einsatz (siehe Abbildung 2). Das Programm leitete den Benutzer durch diverse Konfigurationsschritte, jeder erledigte Menüpunkt änderte seine Farbe von Rot nach Grün. All das gelang mit reinen Bash-Mitteln, für die verschiedenen Farben einschließlich der Cursorsteuerung im Fenster sorgten Terminal-Escape-Sequenzen.
Jenseits der Bash
Zwischen reine Bash-Mittel und eigene, interaktive Programme reihen sich noch Tools wie Dialog [2] oder Xdialog [3] ein. Das erste Werkzeug fußt auf Ncurses, das andere benötigt einen laufenden X-Server. Wer auf möglichst geringe Abhängigkeiten Wert legt, verzichtet natürlich auf solche Pakete. Andererseits sind die interaktiven Widgets beider Pakete deutlich schöner und benutzerfreundlicher als reine Bash-Mittel.
Vorbildliches Checkinstall
Zusammenfassend lässt sich feststellen, dass mit dem Benutzer interagierende Bash-Skripte je nach Anspruch an die Optik mit recht geringem Aufwand implementierbar sind. Neben Eingabefeldern umfasst das Vokabular Menüs und Abfragen (“Sind Sie sicher?”).
Vorbildlich sind Skripte wie etwa Checkinstall [4]. Der Anwender kann das Programm auf Wunsch komplett oder teilweise über Kommandozeilen-Parameter steuern. Alle fehlenden Angaben fragt »checkinstall« dann über interaktive Dialoge ab, so wie es dieser Artikel beschrieben hat. Damit ist das Tool nutzbar, ohne dass der Anwender sich durch lange Hilfeseiten quälen muss. Bei regelmäßigem Gebrauch – etwa aus Makefiles – läuft das Programm aber trotzdem vollautomatisch ab. (jk)
Infos
- Bash-Skript zur Optimierung der WordPress-Datenbank: http://www.techspread.de/7402/bashscript-zur-optimierung-der-wordpress-datenbank
- Dialog: http://www.hightek.org/dialog/
- Xdialog: http://xdialog.dyns.net
- Checkinstall: http://www.asic-linux.com.mx/~izto/checkinstall/






