Grafische Terminal-Programme

Dialogboxen mit Whiptail erstellen

| Autor / Redakteur: Mirco Lang / Stephan Augsten

Whiptail ermöglicht es, einfache Dialogboxen zu erstellen.
Whiptail ermöglicht es, einfache Dialogboxen zu erstellen. (Bild: Mirco Lang / Whiptail)

Grafische Terminal-Programme bringen das Beste aus GUI und Command Line Interpreter zusammen: Ressourcen sparende, einfach zu erstellende Anwendungen und nutzerfreundliche, intuitive Bedienung. Mit Whiptail ist es möglich, solche Eingabedialoge zu basteln.

Gute Tools brauchen nicht unbedingt eine aufwändige Point-and-Click-Oberfläche. Aber Nutzer ausschließlich auf CLI-Ebene anzusprechen, geht auch nur bei einer bestimmten Klientel. Beides vereint Whiptail, das unter Debian und Ubuntu standardmäßig installiert ist.

Was kann Whiptail?

Einfache Dialogboxen, deren Eingaben an einen Command Line Interpreter übergeben wurden, waren früher Gang und Gäbe. Heute kennt man diese Art von Textmenüs noch von der Installation vieler Linux-Distributionen, von einigen Konfigurationswerkzeugen oder sogar kompletten Programmen: Mit den Pfeiltasten navigieren Sie durch Menüs, wählen Tools oder Optionen oder setzen irgendwelche Werte manuell.

Whiptail erstellt solche Menüstrukturen, führt die hinterlegten Funktionen aus und gibt gegebenenfalls ein Resultat aus. Oder anders ausgedrückt: Whiptail ermöglicht es Shell-Skripten, Dialogboxen anzuzeigen und so den Nutzer zu informieren oder Informationen einzuholen.

Die verfügbaren Dialoge:

  • Infobox: Einfacher Infotext.
  • Message-Box: Infotext, der vom Nutzer bestätigt werden muss.
  • Ja/Nein-Box: Einfache Ja-Nein-Abfrage.
  • Eingabebox: Liest Nutzereingaben.
  • Passwortbox: Verdeckte Passworteingabe mit Sternchen.
  • Menüs: Listen mit Optionen.
  • Checkliste: Mehrfachauswahllisten mit Optionen.
  • Radio-Liste: Einfachauswahlliste mit Optionen.
  • Fortschrittsbalken: Animierte oder fixe Anzeige.

Hinzu kommen gerade einmal rund 15 Optionen etwa für Titel, Texte von Buttons und derlei Kleinigkeiten. Whiptail ist also durchaus übersichtlich.

Eine simple Message-Box.
Eine simple Message-Box. (Bild: Lang / Whiptail)

Im Terminal beziehungsweise Skript sieht das dann im einfachsten Fall etwa so aus:

whiptail --msgbox "Hallo Dev-Insider" 20 78

Praxisbeispiel

Im Folgenden sehen Sie den Aufbau eines kleinen Programms „WWWhip“, das drei simple Funktionen bietet: Interne IP anzeigen, externe IP anzeigen und eine beliebige Website anpingen. Dafür kommen aus der obigen Liste die Dialoge Eingabebox, Message-Box, Menü und Fortschrittsbalken zum Einsatz. Dieses rudimentäre Demo-Tool zeigt, wie sich Whiptail in ein Skript einfügen lässt – und darauf sollten Sie recht fix eigene Projekte umsetzen können. Übrigens: Auch für Profi-Skripter ist Whiptail nicht uninteressant, da es sich gut als Zugang zu ausufernden privaten Skriptsammlungen eignet.

Das Skript gliedert sich in zwei Bereiche: Zunächst werden die drei Funktionen festgelegt, anschließend folgen die Menüstruktur und dann die Zuordnung der Funktionen zu den Menüpunkten.

Das Auslesen der externen IP-Adresse übernimmt ein curl-Aufruf der Website ifconfig.me/ip, das Ergebnis landet in der Datei „resultfile“ und der ganze Vorgang wird von einem Whiptail-Fortschrittsbalken begleitet:

function externalip {
   {
      ip=$(curl -s ifconfig.me/ip)
      result="Deine externe IP ist $ip"
      echo $result > resultfile
   } | whiptail --gauge "Externe IP wird über ifconfig.me ermittelt ..." 6 60 50
}

Der Fortschrittsbalken mit manuell übergebenem 50-Prozent-Status.
Der Fortschrittsbalken mit manuell übergebenem 50-Prozent-Status. (Bild: Lang / Whiptail)

Das Speichern in der Datei „resultfile“ ist für die spätere Ausgabe notwendig. Interessant ist hier aber vor allem der Aufruf von „gauge“, also dem Fortschrittsbalken. Hier werden vier Werte übergeben: Infotext, Höhe, Breite und Prozentangabe. Sobald curl-Vorgang und Speicherung abgeschlossen sind, verschwindet der Balken wieder – tendenziell ist er also in diesem Szenario nur für ein Blinzeln zu sehen. Und er wird natürlich fix auf 50 Prozent stehen bleiben, ist also im Grunde lediglich ein Pausenbild.

Das Auslesen der internen IP funktioniert exakt genauso, lediglich die eigentliche Befehlszeile sieht etwas anders aus:

ip=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/')

Mehr Whiptail gibt es in der dritten Funktion zum Anpingen einer Webseite, nämlich eine Nutzereingabe für die Zieladresse und einen animierten Fortschrittsbalken, schließlich kann das Anpingen auch mal länger dauern. Zunächst der Code:

function pingit {
   url=$(whiptail --inputbox "URL angeben" 6 60 3>&1 1>&2 2>&3)
   {
      pingresult=$(ping -c5 $url | grep packets)
      result="Die Ping-Ergebnisse für $url:\n $pingresult"
      echo $result > resultfile
      for ((i = 98 ; i <= 100 ; i+=1)); do
         sleep 0.5
         echo $i
      done
   } | whiptail --gauge "Es werden die Daten von 5 Pings gesammelt ..." 6 60 50
}

Der Aufruf von „whiptail --inputbox“ ist wieder weitgehend trivial: Infotext, Höhe und Breite. Es folgt das etwas Unschöne „3>&1 1>&2 2>&3“, mit dem kurz gesagt STDOUT und STDERR vertauscht werden. Whiptail gibt an STDERR aus und so lässt sich der Inhalt entsprechend nutzen. Das Ergebnis landet dann wieder in der Datei „resultfile“.

Bevor wieder an Whiptail geleitet wird, kommt nun aber eine kleine for-Schleife, die einfach im 0,5-Sekunden-Takt hochzählt und die Zahl ausgibt. Diese per Pipe übergebene Zahl frisst Whiptail als Prozentangabe. Im Beispiel wird der Fortschrittsbalken mit einer Vorgabe von 50 eingeblendet – schließlich gibt es keine echten Werte vom ping-Prozess, die für eine echte Schätzung verwendet werden könnten.

Die 50 bleibt, bis ping fertig ist, dann wird die for-Schleife mit den Werten 98 und 99 durchlaufen – woraufhin der Fortschrittsbalken animiert die letzen Schritte bis zur Fertigstellung anzeigt. Das ist in diesem Fall natürlich eine Verzögerung des Ganzen, aber ein netter Workaround, um Nutzer nicht auf eine gar nichts tuende Kommandozeile schauen zu lassen. Hier gibt es aber viele Möglichkeiten, das „gauge“-Element mit Futter zu versorgen.

Eine Demo-Anwendung in vertrauter Optik.
Eine Demo-Anwendung in vertrauter Optik. (Bild: Lang / Whiptail)

Und nun folgt die eigentliche grafische Oberfläche. Das Prinzip: Eine Endlosschleife hält das Konstrukt am Leben, die Menüpunkte landen in einem assoziativen Array und eine case-Abfrage ordnet den (ausgewählten) Menüpunkten die obigen Funktionen zu. Zum Abschluss wird das Ergebnis, also zum Beispiel die interne IP-Adresse, über eine Message-Box ausgegeben. Hier der Code:

while [ 1 ]
do
   # Aufbau des Menüs
   CHOICE=$(
      whiptail --title "Mein kleines Infosystem" --menu "Bitte Tool auswählen" 16 100 9 \
      "1)" "Meine externe IP-Adresse" \
      "2)" "Meine interne IP-Adresse" \
      "3)" "Eine URL anpingen" \
      "4)" "Programm beenden" 3>&2 2>&1 1>&3
   )

   # Zuordnung Funktionen zu Menüpunkten
   case $CHOICE in

      "1)")
         externalip
         read -r result < resultfile
      ;;

      "2)")
         internalip
         read -r result < resultfile
      ;;

      "3)")
         pingit
         read -r result < resultfile
      ;;

      "4)")
         exit
      ;;
   esc

   # Ausgabe über Variable $result
   whiptail --msgbox "$result" 20 78
done

Und wieder ist der Whiptail-Aufruf für das Menü trivialster Natur: Titel, Menüname, Höhe, Breite, Listenhöhe und dann wiederholt Tag und Item, hier also die vorgestellte Menünummer als Tag und kurze Erklärungstexte als Items. Am Ende des Menüs folgt der schon bekannte Switch von STDERR und STDOUT, da die Tags nach Auswahl durch den Nutzer an STDERR ausgegeben werden.

Die case-Abfrage führt nun für jedes denkbare Tag Befehle aus: In den ersten drei Fällen die oben deklarierten Funktionen, dann „exit“ zum Beenden des Menüs. Die Funktionen oben resultierten alle in der Datei „resultfile“, die nun entsprechend genutzt wird, um abermals die Variable „result“ per read-Befehl zu füllen.

Wurde der entsprechende Befehl ausgeführt, folgt der letzte Whiptail-Aufruf mit der bereits aus der Einleitung bekannten Message-Box (msgbox) und eben dem Inhalt der Variablen „$result“.

Natürlich könnten Sie auch auf explizite Funktionen verzichten und direkt in der case-Abfrage Befehle hinterlegen, wie es auch beim exit-Befehl der Fall ist. Dann bräuchten Sie auch keine resultfile-Datei als Zwischenspeicher, da die result-Variable hier natürlich überall zur Verfügung steht.

Whiptail zum Stöbern

Grundsätzlich funktionieren alle anderen Elemente sehr ähnlich – und lassen sich freilich auch auf andere Art und Weise miteinander und mit anderem Code verweben. Die Anwendungsgebiete sind vielfältig.

Klar, Installationsroutinen schreien geradezu nach einer solchen Menüführung und auch die Konfiguration von Programmen ist so für viele Nutzer deutlich einfacher als das Editieren von Textdateien. Aber es lassen sich eben auch ganze Programme daraus stricken. Wer viel im Terminal arbeitet, wird sich zum Beispiel seine Alias für alles Wichtige bereit legen.

Doch es dürfte Dutzende komplexerer Befehlseingaben geben, die nur einmal alle paar Monate mal zum Einsatz kommen – und nun wirklich niemand ständig im Kopf hat. Mit einem (verschachtelten) Menü ließe sich wunderbar auch in riesigen Sammlungen stöbern. Nach etwas Konkretem suchen geht per CLI perfekt. Aber das Stöbern, das ist allemal besser in einer grafischen Umgebung aufgehoben.

Kommentare werden geladen....

Kommentar zu diesem Artikel

Der Kommentar wird durch einen Redakteur geprüft und in Kürze freigeschaltet.

Anonym mitdiskutieren oder einloggen Anmelden

Avatar
Zur Wahrung unserer Interessen speichern wir zusätzlich zu den o.g. Informationen die IP-Adresse. Dies dient ausschließlich dem Zweck, dass Sie als Urheber des Kommentars identifiziert werden können. Rechtliche Grundlage ist die Wahrung berechtigter Interessen gem. Art 6 Abs 1 lit. f) DSGVO.
  1. Avatar
    Avatar
    Bearbeitet von am
    Bearbeitet von am
    1. Avatar
      Avatar
      Bearbeitet von am
      Bearbeitet von am

Kommentare werden geladen....

Kommentar melden

Melden Sie diesen Kommentar, wenn dieser nicht den Richtlinien entspricht.

Kommentar Freigeben

Der untenstehende Text wird an den Kommentator gesendet, falls dieser eine Email-hinterlegt hat.

Freigabe entfernen

Der untenstehende Text wird an den Kommentator gesendet, falls dieser eine Email-hinterlegt hat.

copyright

Dieser Beitrag ist urheberrechtlich geschützt. Sie wollen ihn für Ihre Zwecke verwenden? Kontaktieren Sie uns über: support.vogel.de/ (ID: 46115218 / Betriebssysteme)