1863 Stimmen

Wie fordere ich Eingaben für Ja/Nein/Abbrechen in einem Linux-Shell-Skript ab?

Ich möchte die Eingabe in einem Shell-Skript pausieren und den Benutzer nach Entscheidungen fragen.
Die Standardfrage für die Typen Ja, Nein oder Abbrechen.
Wie kann ich das in einem typischen Bash-Prompt erreichen?

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/43532

4 Stimmen

Jeder, der von ZSH hierher kommt, siehe diese Antwort für die Verwendung des read Befehls zur Aufforderung

2 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.

13voto

Tom Hale Punkte 32065

Nur eine einzige Taste drücken

Hier ist ein längerer, aber wiederverwendbarer und modularer Ansatz:

  • Gibt 0\=ja und 1\=nein zurück
  • Kein Drücken von Enter erforderlich - nur ein einzelnes Zeichen
  • Kann Enter drücken, um die Standardeinstellung zu akzeptieren
  • Kann die Standardeinstellung deaktivieren, um eine Auswahl zu erzwingen
  • Funktioniert sowohl für zsh als auch für bash.

Voreinstellung auf "nein" beim Drücken von Enter

Beachten Sie, dass das N großgeschrieben ist. Hier wird Enter gedrückt, um die Standardeinstellung zu akzeptieren:

$ confirm "Zeige gefährlichen Befehl" && echo "rm *"
Zeige gefährlichen Befehl [y/N]?

Beachten Sie auch, dass [y/N]? automatisch hinzugefügt wurde. Das Standard-"nein" wird akzeptiert, also wird nichts ausgegeben.

Erneute Aufforderung, bis eine gültige Antwort gegeben wird:

$ confirm "Zeige gefährlichen Befehl" && echo "rm *"
Zeige gefährlichen Befehl [y/N]? X
Zeige gefährlichen Befehl [y/N]? y
rm *

Voreinstellung auf "ja" beim Drücken von Enter

Beachten Sie, dass das Y großgeschrieben ist:

$ confirm_yes "Zeige gefährlichen Befehl" && echo "rm *"
Zeige gefährlichen Befehl [Y/n]?
rm *

Oben habe ich gerade Enter gedrückt, also wurde der Befehl ausgeführt.

Keine Voreinstellung bei Enter - erfordert y oder n

$ get_yes_keypress "Hier kannst du nicht Enter drücken. Gefällt dir das [y/n]? "
Hier kannst du nicht Enter drücken. Gefällt dir das [y/n]? k
Hier kannst du nicht Enter drücken. Gefällt dir das [y/n]?
Hier kannst du nicht Enter drücken. Gefällt dir das [y/n]? n
$ echo $?
1

Hier wurde 1 oder falsch zurückgegeben. Beachten Sie, dass Sie bei dieser Low-Level-Funktion Ihren eigenen [y/n]?-Prompt angeben müssen.

Code

# Liest ein einzelnes Zeichen von /dev/tty, mit der Eingabeaufforderung "$*"
# Hinweis: Durch Drücken von Enter wird eine leere Zeichenfolge zurückgegeben. Möglicherweise eine Version mit X am Ende, die dann im Aufrufer entfernt wird?
# Siehe https://unix.stackexchange.com/a/367880/143394 für den Umgang mit Multibyte usw.
function get_keypress {
  local REPLY IFS=
  >/dev/tty printf '%s' "$*"
  [[ $ZSH_VERSION ]] && read -rk1  # Verwenden von -u0 zum Lesen von STDIN
  # Siehe https://unix.stackexchange.com/q/383197/143394 bezüglich '\n' -> ''
  [[ $BASH_VERSION ]] && 
# Verwendung: confirm "Gefahr. Bist du sicher?" && rm *
function confirm {
  local prompt="${*:-Bist du sicher} [y/N]? "
  get_yes_keypress "$prompt" 1
}    

# Aufforderung zur Bestätigung, Standardeinstellung auf JA bei 
function confirm_yes {
  local prompt="${*:-Bist du sicher} [Y/n]? "
  get_yes_keypress "$prompt" 0
}

0 Stimmen

Als ich dieses Skript getestet habe, anstatt der obigen Ausgabe habe ich `Zeige gefährlichen Befehl [j/N]? [j/n]?` und `Zeige gefährlichen Befehl [J/n]? [j/n]?` erhalten.

0 Stimmen

Vielen Dank @IliasKarim, ich habe das gerade behoben.

12voto

Jahid Punkte 19666
lesen -e -p "Geben Sie Ihre Auswahl ein: " auswahl

Die Option -e ermöglicht es dem Benutzer, die Eingabe mit den Pfeiltasten zu bearbeiten.

Wenn Sie eine Vorschlag als Eingabe verwenden möchten:

lesen -e -i "ja" -p "Geben Sie Ihre Auswahl ein: " auswahl

Die Option -i zeigt einen Vorschlag als Eingabe an.

0 Stimmen

Yap, -e -i funktionieren nicht in sh (Bourne-Shell), aber die Frage ist speziell mit bash markiert..

10voto

Ctrl-C Punkte 4021

Einzeln:

read -p "Fortfahren? [Enter] Ja, [Strg]+[C] Nein." 

Dies setzt voraus, dass "Nein" und "Abbrechen" das gleiche Ergebnis haben, daher kein Grund, sie unterschiedlich zu behandeln.

7voto

Yokai Punkte 1108

Ich habe festgestellt, dass niemand eine Antwort mit einem mehrzeiligen Echo-Menü für solch einfache Benutzereingaben gepostet hat, also hier ist meine Lösung:

#!/bin/bash

function ask_user() {    

echo -e "
#~~~~~~~~~~~~#
| 1.) Ja     |
| 2.) Nein   |
| 3.) Beenden|
#~~~~~~~~~~~~#\n"

read -e -p "Wähle 1: " choice

if [ "$choice" == "1" ]; then

    do_something

elif [ "$choice" == "2" ]; then

    do_something_else

elif [ "$choice" == "3" ]; then

    clear && exit 0

else

    echo "Bitte wähle 1, 2 oder 3." && sleep 3
    clear && ask_user

fi
}

ask_user

Diese Methode wurde mit der Hoffnung gepostet, dass jemand sie nützlich und zeitsparend findet.

6voto

Samir Kape Punkte 1263

Überprüfen Sie das

lesen -p "Weitermachen? (j/n): " bestätigen && [[ $bestätigen == [jJ] || $bestätigen == [jJ][aA] ]] || exit 1

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