840 Stimmen

Wie kann ich einen Benutzer in einem Bash-Skript zur Bestätigung auffordern?

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?

1402voto

Dennis Williamson Punkte 322329
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]$ ]]

250voto

ghostdog74 Punkte 305138

Fall/esac verwenden.

read -p "Continue (y/n)?" choice
case "$choice" in 
  y|Y ) echo "yes";;
  n|N ) echo "no";;
  * ) echo "invalid";;
esac

Vorteil:

  1. ordentlicher
  2. kann "OR"-Bedingung einfacher verwenden
  3. 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.

72voto

Adam Hupp Punkte 1363

Versuchen Sie die read Shell-Einrichtung:

read -p "Continue (y/n)?" CONT
if [ "$CONT" = "y" ]; then
  echo "yaaa";
else
  echo "booo";
fi

59voto

SergioAraujo Punkte 9813

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

34voto

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!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X