Ich möchte gdialog
Benutzereingaben entgegennehmen und sie in der Shell an Switch Case weitergeben. Unten ist mein Code:
#!/bin/sh
which gdialog 2> /dev/null && DIALOG=gdialog || DIALOG=dialog
end () {
# rm -f $FILE1 $FILE2 $ERROR
echo "User pressed cancel!"
exit
}
while true
do
choice=$($DIALOG --title "Messenger" --menu "Command" 8 35 8 \
"Date" "Get today's date" \
"Time" "Get today's time")|| end
# echo $choice
case "$choice" in
"Date")
MSG="Date is requested"
echo $MSG
$DIALOG --yesno "$MSG" 7 20 || end
;;
"Time")
MSG="Time is requested!"
$DIALOG --yesno "$MSG" 7 20 || end
;;
esac
done
Das Problem besteht darin, dass der Switch-Case ausgeführt wird und der Kontrollfluss den ersten oder zweiten Case erreicht, die Zeile nach der Variablendeklaration jedoch MSG
nicht ausgeführt wird. Ich möchte den Benutzer mit „yes“/„no“ fragen, ob er fortfahren möchte gdialog
. Was mache ich hier falsch?
Antwort1
Die Befehlsersetzung wird durch die Standardausgabe des Befehls ersetzt. Dialog verwendet stdout, um seine Benutzeroberfläche anzuzeigen, gdialog verwendet es meines Wissens überhaupt nicht. Beide verwenden stderr, um das Ergebnis zurückzugeben.
Eine Möglichkeit, dafür zu sorgen, dass Ihr Skript wie erwartet funktioniert, besteht darin, bei der Befehlsersetzung stdout durch stderr zu ersetzen:
choice=$($DIALOG --title "Messenger" --menu "Command" 8 35 8 \
"Date" "Get today's date" \
"Time" "Get today's time" 3>&2 2>&1 1>&3)|| end
Antwort2
dialog
schreibt sein Ergebnis in den Standardfehler, sofern Sie nicht eine Umleitung durchführen oder die --stdout
Option verwenden (da es wie jede Curses-Anwendung seine Anzeige standardmäßig in die Standardausgabe schreibt und den Standardfehler meldet). Bei würden Sie das nicht bemerken gdialog
, da es seine Anzeige in ein anderes Fenster schreibt.
Aus diesem Grund gdialog
würde ich schreibenNichtszur Standardausgabe und $choice
wäre leer. Das Skript führt die Case-Anweisung aus, aber stimmt mit keinem der Fälle überein. In der Regel sollten Case-Anweisungen einen Standardwert haben, z. B.*)
damit Sie eine Nachricht hinterlassen könnenDortund sehen Sie, was los ist.
Nicht Teil der Frage, aberWieum das Problem zu umgehen, scheint zu erwarten. Das Skript verweist auf gdialog
, was wahrscheinlich ein Skript ist, das zenity
(dasOriginalgdialog
Istlange vorbei). Keines der beiden Programme bietet diese --stdout
Option an, obwohl sie wahrscheinlich schon vor beiden Programmen existierte (sieheChangelog-Eintrag von 2000). Sie können das in der Shell umgehen, indem Sie die Dateideskriptoren gegen die Standardausgabe und den Fehler austauschen. Das ist seit Ende 2000 auch in den Beispielskripten von Dialog enthalten, und zwar auf Grundlage eines Vorschlags von Carey Evans (Entwickler von tn5250):
Es ist möglich, die Ausgabe des Dialogs zu erfassen, ohne temporäre Dateien überhaupt, wie ich es im „xt5250“-Skript von tn5250 getan habe: Ausführung 3>&1 XT5250_HOST="`$DIALOG --backtitle "xt5250" --title "Mit Host verbinden" \ --inputbox "Geben Sie den Namen oder die IP-Adresse des Hosts ein, mit dem eine Verbindung hergestellt werden soll:" \ 7 60 2>&1 1>&3`" ret=$? ausführen 3>&- Vielleicht könnten Sie in Erwägung ziehen, so etwas zu verwenden, anstatt temporäre Dateien. Der Trick mit zusätzlichen FDs wird etwas schwierig aber lesen. > (es sind jedoch Beispiele – wie viel Arbeit muss ich investieren, um sie sicher zu machen?) Die Leute werden sie ausschneiden und einfügen.
Wenn man dem zustimmt, hilft es, Skripte anzuhalten und zu erklären. Die Bash-Dokumentation hilft hier weiter, mitVerschieben von DateideskriptorenDieses Skript
(sh myscript.sh 3>&2 2>&1 1>&3) 2>/dev/null
kann von rechts nach links gelesen werden als (a) Verschieben des Dateideskriptors 1 (stdout) bis 3, 2 (stderr) auf 1 und dann auf 3 (ursprünglichstdout) zu 2.
Sie könnten Ihr Skript also verbessern, indem Sie die gleiche Reihe von Änderungen in die Dateideskriptoren einfügen:
3>&2 2>&1 1>&3
in der Zuordnung zu choice
:
choice=$($DIALOG --title "Messenger" --menu "Command" 8 35 8 \
"Date" "Get today's date" \
"Time" "Get today's time" 3>&2 2>&1 1>&3 )|| end
Weiterführende Literatur: