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.

3voto

rubo77 Punkte 17467

Dies ist das, was ich normalerweise in einem Skript/Funktion benötige:

  • Standardantwort ist Ja, wenn Sie ENTER drücken
  • nehmen Sie auch z an (für den Fall, dass Sie auf der QWERTZ-Tastatur sind)
  • akzeptieren Sie auch andere Sprachen ("ja", "Oui", ...)
  • behandeln Sie den richtigen Ausstieg, falls Sie sich innerhalb einer Funktion befinden

    while true; do read -p "Fortsetzen [Y/n]? " -n 1 -r -e yn case "${yn:-Y}" in [YyZzOoJj] ) echo; break ;; [Nn] ) [[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 ;; # Behandlung von Beendigungen aus Shell oder Funktion, aber nicht Beenden der interaktiven Shell

    • ) echo "Bitte antworten Sie mit ja oder nein.";; esac done echo "und los geht's!"

3voto

ccDict Punkte 593

Als Freund eines Einzeilers habe ich folgendes verwendet:

while [ -z $prompt ]; do read -p "Weiter (j/n)?" choice;case "$choice" in y|Y ) prompt=true; break;; n|N ) exit 0;; esac; done; prompt=;

In langer Form geschrieben funktioniert es so:

while [ -z $prompt ];
  do read -p "Weiter (j/n)?" choice;
  case "$choice" in
    y|Y ) prompt=true; break;;
    n|N ) exit 0;;
  esac;
done;
prompt=;

0 Stimmen

Kannst du die Verwendung der prompt-Variablen klären? Es sieht für mich so aus, als wäre sie nach der Einzeiler gelöscht, also wie verwendest du die Zeile, um IRGENDWAS zu tun?

0 Stimmen

Der Prompt wird nach der while-Schleife gelöscht. Ich möchte, dass die Prompt-Variable im Anschluss initialisiert wird (da ich die Anweisung häufiger verwende). Wenn diese Zeile in einem Shell-Skript steht, wird es nur fortgesetzt, wenn y|Y eingegeben wird, andernfalls wird das Skript beendet, wenn n|N eingegeben wird, oder es wird nach Eingabe von allem anderen erneut nach Eingabe gefragt.

3voto

Eduardo Cuomo Punkte 15791

Ja / Nein / Abbrechen

Funktion

#!/usr/bin/env bash
@confirm() {
  local message="$*"
  local result=''

  echo -n "> $message (Ja/Nein/Abbrechen) " >&2

  while [ -z "$result" ] ; do
    read -s -n 1 choice
    case "$choice" in
      y|Y ) result='Y' ;;
      n|N ) result='N' ;;
      c|C ) result='C' ;;
    esac
  done

  echo $result
}

Verwendung

case $(@confirm 'Bestätigen?') in
  Y ) echo "Ja" ;;
  N ) echo "Nein" ;;
  C ) echo "Abbrechen" ;;
esac

Bestätigen mit sauberer Benutzereingabe

Funktion

#!/usr/bin/env bash
@confirm() {
  local message="$*"
  local result=3

  echo -n "> $message (j/n) " >&2

  while [[ $result -gt 1 ]] ; do
    read -s -n 1 choice
    case "$choice" in
      y|Y ) result=0 ;;
      n|N ) result=1 ;;
    esac
  done

  return $result
}

Verwendung

if @confirm 'Bestätigen?' ; then
  echo "Ja"
else
  echo "Nein"
fi

3voto

oOpSgEo Punkte 183

Ich habe die case Anweisung schon ein paar Mal in einem solchen Szenario verwendet, die Verwendung der case-Anweisung ist ein guter Weg, um damit umzugehen. Eine while-Schleife, die den case-Block umschließt und eine boolesche Bedingung verwendet, kann implementiert werden, um noch mehr Kontrolle über das Programm zu haben und viele andere Anforderungen zu erfüllen. Nachdem alle Bedingungen erfüllt sind, kann ein break verwendet werden, um die Kontrolle wieder an den Hauptteil des Programms zu übergeben. Um auch andere Bedingungen zu erfüllen, können natürlich zusätzlich bedingte Anweisungen hinzugefügt werden, um die Kontrollstrukturen: die case-Anweisung und möglicherweise die while-Schleife zu begleiten.

Beispiel für die Verwendung einer case-Anweisung zur Erfüllung Ihrer Anfrage

#! /bin/sh 

# Für potenzielle Benutzer von BSD, oder anderen Systemen die kein
# Bash-Binary in /bin haben, wird das Skript an eine Bourne-Shell, z.B. /bin/sh gerichtet

# HINWEIS: Es scheint am besten zu sein, für die Behandlung von Benutzereingabefehlern oder
# Ausnahmen zu entscheiden, die durch die Eingabe erforderlich sind
# des Prompts in einer case-Anweisung (case-Kontrollstruktur),

echo Möchten Sie die Option ausführen: "(Y|N)"

read inPut

case $inPut in
    # das Ausführen eines Befehls, umschlossen von
    # Backticks (``) führt den Befehl aus
    "Y") echo `Mach etwas Verrücktes`
    ;;
    # je nach Szenario die andere Option ausführen
    # oder als Standard belassen
    "N") echo `eine andere Option ausführen`
    ;;
esac

exit

3voto

Joshua Goldberg Punkte 4405

Eine einfache Möglichkeit, dies zu tun, ist mit xargs -p oder gnu parallel --interactive.

Ich mag das Verhalten von xargs etwas besser dafür, weil es jeden Befehl sofort nach der Eingabeaufforderung ausführt, wie andere interaktive Unix-Befehle, anstatt die Zustimmungen zum Ausführen am Ende zu sammeln. (Sie können nachdem Sie die gewünschten Befehle durchgegangen sind, mit Strg-C abbrechen.)

zum Beispiel,

echo *.xml | xargs -p -n 1 -J {} mv {} backup/

0 Stimmen

Nicht schlecht, aber xargs --interactive ist auf Ja oder Nein beschränkt. Solange das alles ist, was Sie brauchen, kann das ausreichen, aber meine ursprüngliche Frage gab ein Beispiel mit drei möglichen Ergebnissen. Mir gefällt wirklich gut, dass es jedoch streambar ist; viele gängige Szenarien würden von seiner Fähigkeit, gepiped zu werden, profitieren.

0 Stimmen

Ich verstehe. Meine Überlegung war, dass "abbrechen" einfach bedeutet, die weitere Ausführung zu stoppen, was übersteuert werden kann über Strg-C, aber wenn du bei Abbrechen (oder bei Nein) etwas Komplexeres tun musst, reicht das nicht aus.

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