Ich möchte eine schnelle "sind Sie sicher?" Aufforderung zur Bestätigung am Anfang eines potenziell gefährlichen Bash-Skripts, was ist der einfachste/beste Weg, dies zu tun?
Antworten
Zu viele Anzeigen?read -p "Are you sure? " -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
# do dangerous stuff
fi
I aufgenommen levislevis85 Vorschlag (danke!) und fügte die -n
Option zu read
um ein Zeichen zu akzeptieren, ohne die Taste Enter . Sie können eine oder beide dieser Möglichkeiten nutzen.
Die verneinte Form könnte auch wie folgt aussehen:
read -p "Are you sure? " -n 1 -r
echo # (optional) move to a new line
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell
fi
Wie Erich jedoch feststellte, könnte die negierte Form unter bestimmten Umständen, z. B. bei einem Syntaxfehler, der dadurch verursacht wird, dass das Skript in der falschen Shell ausgeführt wird, dem Skript erlauben, mit den "gefährlichen Dingen" fortzufahren. Der Fehlermodus sollte das sicherste Ergebnis bevorzugen, so dass nur die erste, nicht-negierte if
verwendet werden sollte.
Erläuterung:
El read
gibt die Eingabeaufforderung ( -p "prompt"
) akzeptiert dann ein Zeichen ( -n 1
) und akzeptiert Backslashes wörtlich ( -r
) (sonst read
würde den Backslash als Escape-Zeichen betrachten und auf ein zweites Zeichen warten). Die Standardvariable für read
um das Ergebnis zu speichern, ist $REPLY
wenn Sie einen solchen Namen nicht angeben: read -p "my prompt" -n 1 -r my_var
El if
Anweisung verwendet einen regulären Ausdruck, um zu prüfen, ob das Zeichen in $REPLY
Übereinstimmungen ( =~
) ein groß- oder kleingeschriebenes "Y". Der hier verwendete reguläre Ausdruck lautet "eine Zeichenfolge, die mit ( ^
) und nur aus einem Zeichen aus einer Liste von Zeichen in einem Klammerausdruck besteht ( [Yy]
) und Ende ( $
)". Die Verankerungen ( ^
y $
) verhindern den Abgleich längerer Zeichenfolgen. In diesem Fall helfen sie dabei, die Ein-Zeichen-Grenze zu verstärken, die in der read
comando.
Die negierte Form verwendet den logischen Operator "nicht" ( !
) zu entsprechen ( =~
) jedes Zeichen, das nicht "Y" oder "y" ist. Ein alternativer Weg, dies auszudrücken, ist weniger lesbar und drückt meiner Meinung nach die Absicht in diesem Fall nicht so klar aus. Allerdings würde es so aussehen: if [[ $REPLY =~ ^[^Yy]$ ]]
Fall/esac verwenden.
read -p "Continue (y/n)?" choice
case "$choice" in
y|Y ) echo "yes";;
n|N ) echo "no";;
* ) echo "invalid";;
esac
Vorteil:
- ordentlicher
- kann "OR"-Bedingung einfacher verwenden
- kann einen Zeichenbereich verwenden, z. B. [yY][eE][sS], um das Wort "ja" zu akzeptieren, wobei jedes seiner Zeichen sowohl in Klein- als auch in Großbuchstaben sein kann.
Auf diese Weise erhalten Sie 'y' 'ja' oder 'Enter'.
read -r -p "Are you sure? [Y/n]" response
response=${response,,} # tolower
if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
your-action-here
fi
Wenn Sie zsh verwenden, versuchen Sie dies:
read "response?Are you sure ? [Y/n] "
response=${response:l} #tolower
if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
your-action-here
fi
Hier ist die Funktion, die ich verwende:
function ask_yes_or_no() {
read -p "$1 ([y]es or [N]o): "
case $(echo $REPLY | tr '[A-Z]' '[a-z]') in
y|yes) echo "yes" ;;
*) echo "no" ;;
esac
}
Und ein Beispiel, das es verwendet:
if [[ "no" == $(ask_yes_or_no "Are you sure?") || \
"no" == $(ask_yes_or_no "Are you *really* sure?") ]]
then
echo "Skipped."
exit 0
fi
# Do something really dangerous...
- Die Ausgabe ist immer "ja" oder "nein".
- Standardmäßig ist es "nein".
- Alles außer "y" oder "yes" gibt "no" zurück, also ist es ziemlich sicher für ein gefährliches Bash-Skript
- Groß- und Kleinschreibung spielt keine Rolle, "Y", "Yes" oder "YES" funktionieren als "yes".
Ich hoffe, es gefällt Ihnen,
Zum Wohl!
- See previous answers
- Weitere Antworten anzeigen