Formulare

Benötigen Sie nicht nur einfache Formulare, sondern eine komplexe Eingabemaske, so bietet Dialog auch dafür die passenden Elemente. Sie bewegen sich darin mit den Tabulator- und Pfeiltasten. Anfangs erscheint die Syntax unübersichtlich: Es gilt, viel mit Positions- und Größenangaben zu hantieren.

Listing 10 zeigt ein kleines Skript, welches das Editieren von Daten erlaubt und wie diese wieder zurück in Variablen ablegt, um diese dauerhaft zurückzuschreiben. Abbildung 5 zeigt, wie sich welche Positions- und Größenangabe des Befehls in der Maske auswirkt.

Listing 10

#! /bin/sh
a="Herr"
b="Meier"
c="Hans"
dialog --title "Titel" --backtitle "Kundendaten" --ok-label "Speichern" --stdout --form "Kartei"  10 60 3 "Anrede  " 1 1 "$a" 1 15 30 0 "Name " 2 1 "$b" 2 15 30 0 "Vorname  " 3 1 "$c" 3 15 30 0 > ausgabe.txt
a=$(cat ausgabe.txt | head -1)
b=$(cat ausgabe.txt | head -2 | tail -1)
c=$(cat ausgabe.txt | head -3 | tail -1)
rm ausgabe.txt
dialog --title "Titel" --backtitle "Hintergrundtitel" --msgbox "Gespeicherte Werte: \n $a \n $b \n $c " 0 0
Abbildung 5: Positions- und Größenangaben für die Elemente des Formulars.

Damit das Umleiten der Ausgabe in eine Datei klappt, setzen Sie vor --form zwingend die zusätzliche Anweisung --stdout ein. In der Nachrichtenbox (msgbox) verwenden Sie das Zeichen für ein Newline (\n), um den Wert jeder Variablen in einer neuen Zeile auszugeben.

Formulare mit der Funktion inputmenu benötigen weniger Größen- und Positionsparameter, jedoch erhalten Sie am Ende nicht die Daten sämtlicher Felder. Je Dialog-Aufruf besteht zudem nur die Möglichkeit, ein einzelnes Feld zu ändern.

Die Ausgabe umfasst die Aktion (RENAMED), den Feldbezeichner und die Daten. Damit die Ausgabe funktioniert, müssen Sie wie zuvor bei --inputmenu die Option --stdout setzen. Das Nachbearbeiten der Daten erfolgt mit cut (Listing 11).

Listing 11

#! /bin/sh
neuwert=$(dialog --title "Titel" --backtitle "Hintergrundtitel" --stdout --inputmenu "MENÜÜBERSCHRIFT" 17 60 15 "Zeile-1 >" "Wert 1" "Zeile-2 >" "Wert 2" "Zeile-3 >" "")
spalte=$(echo $neuwert | cut -d \> -f 1 | cut -b 9-)
eintrag=$(echo $neuwert | cut -d \> -f 2 | cut -b 2-)
dialog --title "Titel" --backtitle "Hintergrundtitel" --msgbox "Gespeicherte Werte: \n $neuwert \n $spalte \n $eintrag " 0 0

Wichtig ist, dass Sie als Feldbezeichner ein zusammenhängendes Wort ohne Leerzeichen verwenden. Bei Datenbanken bietet sich dazu der entsprechende Feldname an. Auf diese Weise fällt es leicht, eine SQL-Anweisung mit den passenden Variablen zu versehen.

Eine komfortable Möglichkeit zur Eingabe eines Datums bietet die Funktion --calendar. Beim Aufruf sehen Sie den aktuellen Monat, in der linken Spalte die Kalenderwoche. Mit den Cursor- und Bild-auf/ab-Tasten wechseln Sie zu einem anderen Datum. Mit dem Betätigen der Schaltfläche OK gibt das Widget den vorher markierten Wert aus.

Um eine Variable zu belegen, lenken Sie wieder über --stdout die Ausgabe um. Weil Dialog die Teile des Datums mit einem Schrägstrich unterteilt, ersetzen Sie mittels tr diese durch den hierzulande üblichen Punkt. Das Listing 12 zeigt, wie ein entsprechendes Skript aufgebaut ist. Ein Bild dazu finden Sie in der Tabelle "Fenstertypen".

Listing 12

#! /bin/sh
a=$(dialog --title "Titel" --backtitle "Hintergrundtitel" --stdout --calendar "TEXT" 0 0 | tr \/ .)
dialog --title "Titel" --backtitle "Hintergrundtitel" --msgbox "gewähltes Datum: $a " 0 0

Zeitwerte erfassen Sie mittels --timebox. Um den Eingabewert zu übernehmen, schalten Sie wieder --stdout vor. Das Fenster zeigt die Zeit des Aufrufs an. Wollen Sie abweichende Werte eingeben, springen Sie mit den Pfeiltasten in die Eingabefelder und geben andere Daten ein.

Beliebige alphanumerische Werte erfassen Sie in einer Eingabebox (--inputbox). Das Belegen einer Variablen innerhalb eines Skripts geschieht mittels vorangestelltem --stdout. Sie haben die Möglichkeit, eine editierbare Vorgabe zu übergeben. Der Vorgang passt in eine Zeile:

a=$(dialog --title "Titel" --backtitle "Hintergrundtitel" --stdout --inputbox "EINGABEÜBERSCHRIFT" 0 0 "VORGABE")

Kleinere Textdateien bearbeiten Sie bei Bedarf in einem Mini-Editor (--editbox). Dabei übergeben Sie als Argument den Namen der Datei. Existiert diese nicht, legen Sie sie mit touch an. Den eingegebenen oder geänderten Text schreiben Sie in eine andere Datei zurück oder hängen ihn an diese an.

Geben Sie für das Fenster die Höhe und Breite an, damit das innere Fenster nicht die Überschrift verdrängt. Wiederum müssen Sie --stdout vorschalten, damit Ihre Eingaben nicht auf der Standard-Fehlerausgabe landen. Sie benötigen nur eine einzige Zeile Shell-Code:

dialog --title "Titel" --backtitle "Hintergrundtitel" --stdout --ok-label "Speichern" --editbox text.txt 20 75  > neu.txt

Das Auswählen von Verzeichnis und Dateiname im Skript erledigen Sie mit --dselect und --fselect. Meist kommen beide in Kombination zum Einsatz. Es empfiehlt sich, für unkundige Benutzer einen Hinweis zum Bedienkonzept anzubringen. Die Auswahl eines Verzeichnisses, das sich auf der gleichen Ebene befindet wie die Vorgabe, erfolgt zunächst über die Pfeiltasten sowie anschließendes Drücken der Leertaste.

Mit --fselect wählen Sie im linken Fensterteil die Pfadangabe, drücken zwei Mal die Leertaste, und erledigen in der rechten Hälfte die Auswahl der Datei. Zwischen den Bereichen wechseln Sie über den Tabulator, innerhalb eines Bereiches navigieren Sie mit den Pfeiltasten.

Das untere Feld erlaubt die manuelle Eingabe. Wenn sich der Cursor darin befindet, springen Sie einfach mit dem Löschen der rechts stehenden Pfadangaben in die nächsthöhere Verzeichnishierarchie zurück (Abbildung 6). Ein Beispiel für die Auswahl von Verzeichnis und Datei finden Sie in Listing 13.

Listing 13

#!/bin/sh
a=$(echo $HOME)
while true
do
  a=$(dialog --title "Titel" --backtitle "Hintergrundtitel" --stdout --fselect $a 0 0)
  dialog --title "Titel" --backtitle "Hintergrundtitel" --defaultno --yesno "$a Übernehmen"  0 0
  if [ $? -eq 0 ]; then
    break
  fi
done
Abbildung 6: Entsprechende Widgets erleichtern die Auswahl von Verzeichnis und Datei.

Eine Mehrfachauswahl bauen Sie mit --checklist auf. Als Ergebnis erhalten Sie das oder die Kennzeichen (Marke) des jeweiligen Eintrags, welche in Anführungszeichen gefasst sind. Als Feldtrenner fungiert das Leerzeichen. Jedem Eintrag geben Sie den Status mit: on steht hier für markiert, off für nicht markiert.

Die Angaben für Höhe (Zeilen), Breite (Zeichen) und Auswahlhöhe (Zeilen) geben Sie vor. Der Wert für die Auswahlhöhe darf hierbei der tatsächlichen Zahl der Wahlmöglichkeiten gleichen. Passt nicht alles in das Fenster, so gibt es die Möglichkeit zu scrollen. Listing 14 zeigt den Code zusammen mit tr, welches die Anführungszeichen entfernt.

Listing 14

#!/bin/sh
a=$(dialog --title "Titel" --backtitle "Hintergrundtitel" --stdout --checklist "AUSWAHLÜBERSCHRIFT" 10 40 3 MARKE-1 "INFO-1" on MARKE-2 "INFO-2" off MARKE-3 "INFO-3" on)
a=$(echo $a | tr -d \")

Die Einfachauswahl baut sich genauso auf wie die Mehrfachauswahl. Sie verwenden den Fenstertyp --radiolist, setzen nur bei einem einzigen Eintrag den Status on, und erhalten den Marker-Wert ohne die Anführungszeichen. Über die Leertaste wählen Sie den entsprechenden Wert aus:

a=$(dialog --title "Titel" --backtitle "Hintergrundtitel" --stdout --radiolist "AUSWAHLÜBERSCHRIFT" 10 40 3 MARKE-1 "INFO-1" on MARKE-2 "INFO-2" off MARKE-3 "INFO-3" off)

Auf diese Weise setzen Sie eine Datensatz-Auswahl für eine Bearbeitungsmaske um. Dabei erstellt das Skript die Auswahl dynamisch aus der Datenabfrage. Die Marke besteht aus der Datensatznummer oder dem eindeutigen Merkmal, mit dem das Skript den Datensatz anschließend für die Maske einliest.

Das Beispiel in Listing 15 zeigt eine SQL-Abfrage mit dem Client Psql für die PostgreSQL-Datenbank. Ziel ist es, die Kundennummer orgnr an den weiteren Teil des Skripts zu übergeben. Die Anweisungen für das Menü mittels --radiolist schreibt das Skript in eine Variable und führt den Code mit eval aus. Für das weitere Gestalten eignen sich je nach Programmierstil die Fenstertypen --form oder --inputmenu.

Listing 15

#!/bin/sh
# Suchmaske für die Datenbankabfrage
sube=$(dialog --title "Kundensuche" --backtitle "Kundendatenverwaltung" --stdout --inputbox "Kundenname eingeben" 0 0 "")
# Prüfen, ob es zutreffende Daten gibt
a=$(psql -t -c "select orgnr from kunden where name = '$sube';")
if [ -z "$a" ]; then
  dialog --title "Kundensuche" --backtitle "Kundendatenverwaltung" --msgbox "Keine passenden Datensätze gefunden! " 0 0
  exit  # oder break, wenn in Schleife!
fi
# Daten für die Einfachauswahl holen und Aufbau Auswahl
#Zähler für den ersten "on"-Status
v=0
teil1=$(echo "a=\`dialog --title \"Kundensuche\" --backtitle \"Kundendatenverwaltung\" --stdout --radiolist \"gefunden: \" 10 40 3 ")
# Kundennummern ermitteln
for i in $(psql -t -c "select orgnr from kunden where name = '$sube' order by name, vorname, gebdat ;"); do
  if [ $v -eq 0 ]; then
    status="on"
    v=1
  else
    status="off"
  fi
  info=$(psql -t -c "select (name || ' ' || vorname || ' ' || gebdat) from kunden where orgnr = $i;";)
  teil2=`echo $teil2 $i \"$info\" $status`
done
auswahlmaske=$(echo "$teil1 $teil2\`")
echo $auswahlmaske
eval $auswahlmaske
dialog --title "Kundensuche" --backtitle "Kundendatenverwaltung" --msgbox "Datensatz Nr. $a ausgewählt " 0 0

Menüs zur Programmsteuerung gelingen mit dem Fenstertyp --menu. Er gibt eine Marke aus, die Sie anschließend auswerten. Wie bei fast allen anderen Wertübergaben schalten Sie auch hier --stdout vor den Fenstertyp. Ein Beispiel dazu zeigt Listing 16.

Listing 16

#!/bin/sh
while true; do
  a=`dialog --title "TITEL" --backtitle "HINTERGRUNDTITEL" --stdout --menu "MENÜÜBERSCHRIFT" 0 0 0 1 "ERSTE" 2 "ZWEITE" 9 "ENDE"`
  if [ $a -eq 1 ]; then
    dialog --title "Titel" --backtitle "Hintergrundtitel" --msgbox "Erster Eintrag gewählt" 0 0
  elif [ $a -eq 2 ]; then
    dialog --title "Titel" --backtitle "Hintergrundtitel" --msgbox "Zweiter Eintrag gewählt" 0 0
  elif [ $a -eq 9 ]; then
    dialog --title "Titel" --backtitle "Hintergrundtitel" --no-label "Programmende" --yes-label "Weitermachen" --yesno "Programmende ?" 0 0
    if [ $? -eq 1 ]; then
      break # oder exit
    fi
  fi
done

Fazit

Möchten Sie Ihre Shell-Skripts mit einer benutzerfreundlichen Oberfläche aufwerten, so finden Sie alles dazu Notwendige im Fundus von Dialog. Benötigen Sie nur einfache Abfrage, dann profitieren Sie sogar von den Vorteilen bereits vorgefertigter Bausteine. Andernfalls stellt sich vermutlich ohnehin die Frage nach einer Alternative zum Shell-Code. 

Der Autor

Harald Zisler beschäftigt sich seit vielen Jahren mit FreeBSD und Linux. Zu Technik- und EDV-Themen verfasst er Artikel und Bücher. Sein neuestes Werk ist die 2. Auflage "Computer-Netzwerke", erschienen bei Galileo Press.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF
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

  • out of the box
    Schreiben Sie gelegentlich Shell-Skripte, in denen Sie Benutzereingaben abfragen wollen? Das Tool dialog stellt Ihnen vielfältige Eingabemechanismen zur Verfügung.
  • Textbasierte User-Interfaces (Teil 1)
    Die Kommandozeile halten viele Anwender für trist und schlecht bedienbar. Das muss aber nicht so sein: Mithilfe von Dialog und Whiptail werten Sie Ihre eigenen Skripts unkompliziert mit Fenstern, Menüs und Dialogen auf.
  • Portabel programmieren mit Dialog, Gdialog und Kdialog
    Bash-Skripte sind meist nur für die Verwendung auf der Kommandozeile gedacht und schrecken Nicht-Experten mit unübersichtlichen Ausgaben ab. Das muss aber nicht so sein: Die Programme Dialog, Gdialog und Kdialog verstecken die Kommandozeile vollständig vor dem Benutzer.
  • Klacker, Klacker, Klick, Klick
    Häufig erledigen Skripte ihre Aufgaben unsichtbar im Hintergrund. Mancher User wünscht sich aber ein visuelles Feedback. Dank Zenity und KDialog fügen sich Ihre Skripte nativ in die KDE- oder Gnome-Umgebung ein.
  • Shell-Skripte mit grafischen Dialogen
    Dass sich Shell-Programmierung und grafische Oberflächen nicht ausschließen, zeigt KDialog: Nie war es leichter, Shell-Skripte um User-Interaktion zu ergänzen.
Kommentare

Infos zur Publikation

LU 12/2017: Perfekte Videos

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

Huawei
Pit Hampelmann, 13.12.2017 11:35, 1 Antworten
Welches Smartphone ist für euch momentan das beste? Sehe ja die Huawei gerade ganz weit vorne. Bi...
Fernstudium Informatik
Joe Cole, 12.12.2017 10:36, 2 Antworten
Hallo! habe früher als ich 13 Jahre angefangen mit HTML und später Java zu programmieren. Weit...
Installation Linux mint auf stick
Reiner Schulz, 10.12.2017 17:34, 3 Antworten
Hallo, ich hab ein ISO-image mit Linux Mint auf einem Stick untergebracht Jetzt kann ich auch...
Canon Maxify 2750 oder ähnlicher Drucker
Hannes Richert, 05.12.2017 20:14, 4 Antworten
Hallo, leider hat Canon mich weiterverwiesen, weil sie Linux nicht supporten.. deshalb hier die...
Ubuntu Server
Steffen Seidler, 05.12.2017 12:10, 1 Antworten
Hallo! Hat jemand eine gute Anleitung für mich, wie ich Ubuntu Server einrichte? Habe bisher...