Drücken Sie die Leertaste, um fortzufahren


73

Wie halte ich ein Bash-Skript an, bis ein Benutzer gedrückt hat Space?

Ich hätte die Frage gerne in meinem Skript

Drücken Sie die Leertaste, um fortzufahren, oder CTRL+, Cum den Vorgang zu beenden

und dann sollte das Skript anhalten und warten, bis die Leertaste gedrückt wird.


All dies und mehr wird in dieser SO-Frage und Antwort angesprochen. Übrigens: Was ist das Linux-Äquivalent zu DOS-Pause?
SLM


Antworten:


58

Sie können verwenden read:

read -n1 -r -p "Press space to continue..." key

if [ "$key" = '' ]; then
    # Space pressed, do something
    # echo [$key] is empty when SPACE is pressed # uncomment to trace
else
    # Anything else pressed, do whatever else.
    # echo [$key] not empty
fi

12
Sie sollten -s hinzufügen, um das gedrückte Zeichen nicht auf dem Terminal auszudrucken. Fügen Sie am Ende einen Zeilenumbruch hinzu, oder die Ausgabe wird direkt in derselben Zeile wie die Frage fortgesetzt. Am besten wäre:read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
rubo77

1
Dieses Skript funktioniert nicht. Habe es gerade unter Red Hat Linux getestet ... Der elseBlock wird immer ausgeführt, auch wenn die Leertaste gedrückt wird.
Robert

3
@ Robert Es ist, weil Sie nicht verwenden bash. Es funktioniert, wenn Sie read _stattdessen eine andere Shell als verwenden bash.
Niklas Rosencrantz

Sollte das ''einen Raum enthalten?
Jose Antonio Dura Olmos

Dies ist ''für eine leere Zeichenfolge. Kein Platz drinnen. Ich denke, es passt auch, wenn Sie ENTER oder TAB
eingeben

44

Die in dieser SO-Frage und Antwort beschriebene Methode ist wahrscheinlich der beste Kandidat für eine Alternative zu dem pauseVerhalten, das Sie unter Windows bei der Ausführung von BAT-Dateien gewohnt sind.

$ read -rsp $'Press any key to continue...\n' -n1 key

Beispiel

Hier führe ich das Obige aus und drücke dann einfach eine beliebige Taste, in diesem Fall die DTaste.

$ read -rsp $'Press any key to continue...\n' -n1 key
Press any key to continue...
$ 

Verweise


Ich meine, warum die $vor der Zeichenfolge hier -rsp $'Press:?
Rubo77

2
@ rubo77 - ah. Auf diese Weise können Sie eine Literalzeichenfolge mit Sonderzeichen erstellen. Es hat die Form: $ '...'
slm

1
@ rubo77 - das ist anders. Das ist ein Dollarzeichen mit doppelten Anführungszeichen, ich habe einen Dollar mit einfachen Anführungszeichen verwendet. Bitte lösche diesen Kommentar, er ist falsch.
slm

1
Oh ich verstehe. Falls Sie maskierte Sequenzen in den Prompt-String einfügen. Siehe wiki.bash-hackers.org/syntax/quoting#ansi_c_like_strings
rubo77

@ rubo77 - Ja, diese Notation ermöglicht das Einfügen von Escape-Sequenzen ohne zusätzliche echo -e "..."Zeilen. In solchen Situationen ist es viel kompakter.
SLM

6
hold=' '
printf "Press 'SPACE' to continue or 'CTRL+C' to exit : "
tty_state=$(stty -g)
stty -icanon
until [ -z "${hold#$in}" ] ; do
    in=$(dd bs=1 count=1 </dev/tty 2>/dev/null)
done
stty "$tty_state"

Dies druckt nun eine Eingabeaufforderung ohne nachfolgende Zeile, verarbeitet sie CTRL+Czuverlässig, ruft sie sttynur so oft auf, wie es erforderlich ist, und stellt den Status der Steuerung genau auf den Zustand zurück, in dem sie sttygefunden wurde. Suchen Sie nach man sttyInformationen zum expliziten Steuern von Echos, Steuerzeichen und allem.

Das könnten Sie auch tun:

printf "Press any key to continue or 'CTRL+C' to exit : "
(tty_state=$(stty -g)
stty -icanon
LC_ALL=C dd bs=1 count=1 >/dev/null 2>&1
stty "$tty_state"
) </dev/tty

Du könntest es mit ENTER, ohne [Tests ]und ohne sttywie machen:

sed -n q </dev/tty

5

Sie könnten eine Funktion dafür erstellen:

pause(){
 read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
}

Dann können Sie dies überall in Ihrem Skript verwenden:

pause

Wenn Sie mit Shell-
Richard

3

Lazy One Liner:

echo "Press any key to continue or Ctrl+C to cancel"
read && do_something.sh

Der Nachteil ist, dass Sie die Kontrolle verlieren, wenn der Benutzer Strg + C drückt. In diesem Fall wird das Skript immer mit Code 130 beendet.


2

Die Einstellung " IFSleere Zeichenfolge" unterdrückt das Standardverhalten von read beim Zuschneiden von Leerzeichen.

try_this() {
  echo -n "Press SPACE to continue or Ctrl+C to exit ... "
  while true; do
    # Set IFS to empty string so that read doesn't trim
    # See http://mywiki.wooledge.org/BashFAQ/001#Trimming
    IFS= read -n1 -r key
    [[ $key == ' ' ]] && break
  done
  echo
  echo "Continuing ..."
}
try_this

UPDATE 2018-05-23: Wir können dies vereinfachen, indem wir die Variable REPLY verwenden, die keiner Wortteilung unterliegt:

try_this() {
  echo -n "Press SPACE to continue or Ctrl+C to exit ... "
  while true; do
    read -n1 -r
    [[ $REPLY == ' ' ]] && break
  done
  echo
  echo "Continuing ..."
}
try_this

1

Hier ist ein Weg, der in beiden Werken bashund zshund sorgt für I / O an das Terminal:

# Prompt for a keypress to continue. Customise prompt with $*
function pause {
  >/dev/tty printf '%s' "${*:-Press any key to continue... }"
  [[ $ZSH_VERSION ]] && read -krs  # Use -u0 to read from STDIN
  [[ $BASH_VERSION ]] && </dev/tty read -rsn1
  printf '\n'
}
export_function pause

Setzen Sie es in Ihr .{ba,z}shrcfür große Gerechtigkeit ein!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.