Mindestens fünf Antworten auf eine generische Frage.
Je nach
- posix konform: könnte auf schlechten Systemen mit generischen Shell Umgebungen
- bash spezifisch: Verwendung der so genannten Bashismen
und wenn Sie wollen
- einfache ``in line'' Frage/Antwort (generische Lösungen)
- hübsch formatierte Schnittstellen, wie ncurses oder mehr grafisch mit libgtk oder libqt...
- Nutzung der leistungsstarken Funktion "Readline History
1. Generische POSIX-Lösungen
Sie könnten die read
Befehl, gefolgt von if ... then ... else
:
echo -n "Is this a good question (y/n)? "
read answer
# if echo "$answer" | grep -iq "^y" ;then
if [ "$answer" != "${answer#[Yy]}" ] ;then # this grammar (the #[] operator) means that the variable $answer where any Y or y in 1st position will be dropped if they exist.
echo Yes
else
echo No
fi
(Dank an Adam Katz' Kommentar : Ersetzte den obigen Test durch einen, der portabler ist und eine Gabelung vermeidet:)
POSIX, aber ein einziges Schlüsselmerkmal
Wenn Sie aber nicht wollen, dass der Benutzer die Taste Return könnten Sie schreiben:
( Bearbeitet: Als @JonathanLeffler zu Recht vorschlagen, Sparen stty-Konfiguration besser sein könnte, als sie einfach dazu zu zwingen vernünftig .)
echo -n "Is this a good question (y/n)? "
old_stty_cfg=$(stty -g)
stty raw -echo ; answer=$(head -c 1) ; stty $old_stty_cfg # Careful playing with stty
if echo "$answer" | grep -iq "^y" ;then
echo Yes
else
echo No
fi
Nota: Dies wurde getestet unter sh , bash , ksh , Bindestrich y busybox !
Dasselbe, aber ich warte ausdrücklich auf y o n :
#/bin/sh
echo -n "Is this a good question (y/n)? "
old_stty_cfg=$(stty -g)
stty raw -echo
answer=$( while ! head -c 1 | grep -i '[ny]' ;do true ;done )
stty $old_stty_cfg
if echo "$answer" | grep -iq "^y" ;then
echo Yes
else
echo No
fi
Verwendung spezieller Tools
Es gibt viele Tools, die mit Hilfe von libncurses
, libgtk
, libqt
oder andere grafische Bibliotheken. Zum Beispiel, mit whiptail
:
if whiptail --yesno "Is this a good question" 20 60 ;then
echo Yes
else
echo No
fi
Je nach System müssen Sie möglicherweise Folgendes ersetzen whiptail
mit einem anderen, ähnlichen Werkzeug:
dialog --yesno "Is this a good question" 20 60 && echo Yes
gdialog --yesno "Is this a good question" 20 60 && echo Yes
kdialog --yesno "Is this a good question" 20 60 && echo Yes
donde 20
ist die Höhe des Dialogfelds in Anzahl der Zeilen und 60
ist die Breite des Dialogfelds. Diese Werkzeuge haben alle nahezu gleich Syntax.
DIALOG=whiptail
if [ -x /usr/bin/gdialog ] ;then DIALOG=gdialog ; fi
if [ -x /usr/bin/xdialog ] ;then DIALOG=xdialog ; fi
...
$DIALOG --yesno ...
2. Bash-spezifische Lösungen
Grundlegend im Einklang 方法
read -p "Is this a good question (y/n)? " answer
case ${answer:0:1} in
y|Y )
echo Yes
;;
* )
echo No
;;
esac
Ich bevorzuge die Verwendung von case
so dass ich sogar testen konnte, ob yes | ja | si | oui
falls erforderlich...
im Einklang con einzelne Taste Funktion
Unter der Bash können wir die Länge der beabsichtigten Eingabe für den Befehl read
Befehl:
read -n 1 -p "Is this a good question (y/n)? " answer
Unter bash, read
Befehl akzeptiert eine Timeout Parameter, der nützlich sein könnte.
read -t 3 -n 1 -p "Is this a good question (y/n)? " answer
[ -z "$answer" ] && answer="Yes" # if 'yes' have to be default choice
3. Einige Tricks für dedizierte Tools
Anspruchsvollere Dialogfelder, die über einfache yes - no
Zwecke:
dialog --menu "Is this a good question" 20 60 12 y Yes n No m Maybe
Fortschrittsbalken:
dialog --gauge "Filling the tank" 20 60 0 < <(
for i in {1..100};do
printf "XXX\n%d\n%(%a %b %T)T progress: %d\nXXX\n" $i -1 $i
sleep .033
done
)
Kleine Demo:
#!/bin/sh
while true ;do
[ -x "$(which ${DIALOG%% *})" ] || DIALOG=dialog
DIALOG=$($DIALOG --menu "Which tool for next run?" 20 60 12 2>&1 \
whiptail "dialog boxes from shell scripts" >/dev/tty \
dialog "dialog boxes from shell with ncurses" \
gdialog "dialog boxes from shell with Gtk" \
kdialog "dialog boxes from shell with Kde" ) || exit
clear;echo "Choosed: $DIALOG."
for i in `seq 1 100`;do
date +"`printf "XXX\n%d\n%%a %%b %%T progress: %d\nXXX\n" $i $i`"
sleep .0125
done | $DIALOG --gauge "Filling the tank" 20 60 0
$DIALOG --infobox "This is a simple info box\n\nNo action required" 20 60
sleep 3
if $DIALOG --yesno "Do you like this demo?" 20 60 ;then
AnsYesNo=Yes; else AnsYesNo=No; fi
AnsInput=$($DIALOG --inputbox "A text:" 20 60 "Text here..." 2>&1 >/dev/tty)
AnsPass=$($DIALOG --passwordbox "A secret:" 20 60 "First..." 2>&1 >/dev/tty)
$DIALOG --textbox /etc/motd 20 60
AnsCkLst=$($DIALOG --checklist "Check some..." 20 60 12 \
Correct "This demo is useful" off \
Fun "This demo is nice" off \
Strong "This demo is complex" on 2>&1 >/dev/tty)
AnsRadio=$($DIALOG --radiolist "I will:" 20 60 12 \
" -1" "Downgrade this answer" off \
" 0" "Not do anything" on \
" +1" "Upgrade this anser" off 2>&1 >/dev/tty)
out="Your answers:\nLike: $AnsYesNo\nInput: $AnsInput\nSecret: $AnsPass"
$DIALOG --msgbox "$out\nAttribs: $AnsCkLst\nNote: $AnsRadio" 20 60
done
Mehr Beispiele? Schauen Sie sich an Whiptail zur Auswahl eines USB-Geräts verwenden y USB-Wechselspeicher-Auswahl: USBKeyChooser
5. Verwendung der Readline-Historie
Beispiel:
#!/bin/bash
set -i
HISTFILE=~/.myscript.history
history -c
history -r
myread() {
read -e -p '> ' $1
history -s ${!1}
}
trap 'history -a;exit' 0 1 2 3 6
while myread line;do
case ${line%% *} in
exit ) break ;;
* ) echo "Doing something with '$line'" ;;
esac
done
Dadurch wird eine Datei erstellt .myscript.history
in Ihrem $HOME
Verzeichnis, dann können Sie die history-Befehle von readline verwenden, wie Up , Down , Ctrl + r und andere.
40 Stimmen
Just als Hinweis: Die Konvention für Aufforderungen besagt, dass wenn Sie eine Option
[yn]
präsentieren, die Großschreibung die Standardeinstellung ist, d.h.[Yn]
wird standardmäßig auf "yes" und[yN]
auf "no" festgelegt. Siehe ux.stackexchange.com/a/40445/435324 Stimmen
Jeder, der von ZSH hierher kommt, siehe diese Antwort für die Verwendung des
read
Befehls zur Aufforderung2 Stimmen
Sie können auch meine zugehörige Frage/Antwort auf U&L.SE zur kanonischen Art, in
bash
zu pausieren, in Betracht ziehen. Die bereitgestellten Ergebnisse können einfach übertragen werden.