Was entspricht Linux der DOS-Pause?


236

Ich habe ein Bash-Shell-Skript, in dem ich die Ausführung anhalten möchte, bis der Benutzer eine Taste drückt. Unter DOS ist dies mit dem Befehl "pause" problemlos möglich. Gibt es ein Linux-Äquivalent, das ich in meinem Skript verwenden kann?

Antworten:


329

read macht dies:

user@host:~$ read -n1 -r -p "Press any key to continue..." key
[...]
user@host:~$ 

Das -n1gibt an, dass nur auf ein einzelnes Zeichen gewartet wird. Das -rversetzt es in den Raw-Modus, was notwendig ist, da es sonst erst registriert wird, wenn Sie so etwas wie einen Backslash drücken, wenn Sie die nächste Taste drücken. Das -pgibt die Eingabeaufforderung an, die in Anführungszeichen gesetzt werden muss, wenn sie Leerzeichen enthält. Das keyArgument ist nur erforderlich, wenn Sie wissen möchten, welche Taste sie gedrückt haben. In diesem Fall können Sie darauf zugreifen $key.

Wenn Sie Bash verwenden, können Sie auch eine Zeitüberschreitung mit angeben -t, die dazu führt, dass das Lesen einen Fehler zurückgibt, wenn eine Taste nicht gedrückt wird. Also zum Beispiel:

read -t5 -n1 -r -p 'Press any key in the next five seconds...' key
if [ "$?" -eq "0" ]; then
    echo 'A key was pressed.'
else
    echo 'No key was pressed.'
fi

5
Genau genommen wäre das so "Enter any non-NUL character to continue". Einige Tasten senden Sie keine Zeichen (wie Ctrl...) und einige senden mehr als ein (wie F1, Home...). bashignoriert NUL-Zeichen.
Stephane Chazelas

2
Normalerweise ist es besser, nach einem bestimmten Schlüssel wie Enter, Leerzeichen oder Y zu fragen. "ANY" kann für einige Benutzer verwirrend sein. Es gibt einen TAB-Schlüssel. Warum also keinen ANY-Schlüssel und sicher gibt es Schlüssel, die möglicherweise gefährlich sind Dies ist heute nicht mehr so ​​relevant, da die Konsole heutzutage normalerweise nur von fortgeschrittenen Computerbenutzern verwendet wird, die "JEDE Taste" richtig interpretieren. Das Apple 2 Design Manual, ziemlich alt, enthält einen interessanten Abschnitt zu diesem Thema ( apple2scans.net/files/1982-A2F2116-m-a2e-aiiedg.pdf ).
Gellweiler

3
Wenn Sie stattdessen die Nachricht verwenden, können Press a key to continue...auch Anfänger die aTaste finden und drücken; o)
DJDaveMark

1
Dies wird Probleme mit command | myscript.shoder haben myscript.sh | command. In dieser Antwort finden Sie eine Lösung.
Tom Hale

Wenn jemand etwas bekommt, read: 1: read: Illegal option -nstellen Sie sicher, dass Sie Ihren Befehl bash -c 'command && command'usw. einschließen, da dieser Fehler wahrscheinlich von kommt sh. Ich mache das in einem Lando-Wrapper-Befehl.
Elijah Lynn

155

Ich benutze diese Methoden sehr oft, die sehr kurz sind und wie @ theunamedguy- und @ Jim-Lösungen aussehen, aber zusätzlich mit Timeout und Silent-Modus.

Ich mag besonders den letzten Fall und verwende ihn in vielen Skripten, die in einer Schleife ausgeführt werden, bis der Benutzer drückt Enter.

Befehle

  • Lösung eingeben

    read -rsp $'Press enter to continue...\n'
  • Escape-Lösung (mit -d $ '\ e')

    read -rsp $'Press escape to continue...\n' -d $'\e'
  • Beliebige Schlüssellösung (mit -n 1)

    read -rsp $'Press any key to continue...\n' -n 1 key
    # echo $key
  • Frage mit vorausgewählter Auswahl (mit -ei $ 'Y')

    read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;
    # echo $key
  • Timeout-Lösung (mit -t 5)

    read -rsp $'Press any key or wait 5 seconds to continue...\n' -n 1 -t 5;
  • Schlafverbesserter Alias

    read -rst 0.5; timeout=$?
    # echo $timeout

Erläuterung

-r gibt den Rohmodus an, der keine kombinierten Zeichen wie "\" oder "^" zulässt.

-s gibt den stillen Modus an und weil wir keine Tastaturausgabe benötigen.

-p $ ' prompt ' gibt die Eingabeaufforderung an, die zwischen $ 'und' liegen muss, um Leerzeichen und maskierte Zeichen zuzulassen. Seien Sie vorsichtig, Sie müssen zwischen einfache Anführungszeichen mit Dollarsymbol setzen, um maskierte Zeichen zu erhalten. Andernfalls können Sie einfache Anführungszeichen verwenden.

-d $ ' \ e ' gibt escappe als Trennzeichen an. Als endgültiges Zeichen für den aktuellen Eintrag können Sie also jedes beliebige Zeichen einfügen. Achten Sie jedoch darauf, ein Zeichen einzugeben, das der Benutzer eingeben kann.

-n 1 gibt an, dass nur ein einziges Zeichen benötigt wird.

-e gibt den Readline-Modus an.

-i $ ' Y ' gibt Y als Anfangstext im Readline-Modus an.

-t 5 gibt eine Zeitüberschreitung von 5 Sekunden an

Taste dient für den Fall, dass Sie die Eingabe kennen müssen, in -n1 Fall die Taste, die gedrückt wurde.

$? dienen dazu, den Exit-Code des letzten Programms zu kennen, zum Lesen, 142 im Falle einer Zeitüberschreitung, 0 korrekte Eingabe. $ Setzen? in einer Variablen so schnell wie möglich, wenn Sie sie nach einigen Befehlen testen müssen, weil alle Befehle $?


1
+1 zum Erklären -s; man readund read --helpHilfe hat unter Ubuntu 10.04.1 LTS nicht geholfen. Bearbeiten: help readtat; ist der Rest veraltet?
Cees Timmerman

1
1+ für die tolle Erklärung: aber ich habe read: -i: invalid optionfür die Ex. read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;auf #osx read -rp $'kill-server: Are you sure (Y/n) : ' -d $'Y' key;funktioniert stattdessen für mich. `
Tino Rüb

Ich weiß nicht, wie es unter OSX funktioniert, aber ich habe einige Tests durchgeführt und es -ifunktioniert perfekt unter Ubuntu. Außerdem weiß ich nicht, wie es unter OSX -dgenauso funktioniert.
y.petremann

Man kann die Eingabeaufforderung sehr schnell und nett
umgehen,

15

readohne Parameter wird nur fortgesetzt, wenn Sie die Eingabetaste drücken. Der DOS- pauseBefehl wird fortgesetzt, wenn Sie eine beliebige Taste drücken. Verwenden read –n1Sie diese Option, wenn Sie dieses Verhalten wünschen.


15

Dies funktionierte für mich bei mehreren Linux-Varianten, bei denen einige dieser anderen Lösungen dies nicht taten (einschließlich der beliebtesten hier). Ich denke, es ist auch besser lesbar ...

echo Press enter to continue; read dummy;

Beachten Sie, dass eine Variable als Argument für angegeben werden muss read.


Diese Antwort löst mein Problem. Wenn ich diese Zeile kopiere und einfüge und aus irgendeinem Grund mehr Zeilen angehängt werden, werden die angehängten Zeilen nicht ausgeführt, wie bei der DOS-Pause
Sérgio

10

read -n1ist nicht tragbar. Ein tragbarer Weg, um dasselbe zu tun, könnte sein:

(   trap "stty $(stty -g;stty -icanon)" EXIT
    LC_ALL=C dd bs=1 count=1 >/dev/null 2>&1
)   </dev/tty

Abgesehen von der Verwendung readkönnen Sie nur eine ENTERTaste drücken, um fortzufahren:

sed -n q </dev/tty

2
status=noneist auch nicht tragbar. Leiten Sie stattdessen stdout und stderr nach / dev / null um. read -r line < /dev/ttysein enought würde ENTER drücken ... .
Stephane Chazelas

@StephaneChezales danke - das wusste ich nicht. Ich werde es jetzt reparieren. Nochmals vielen Dank - behoben. Du bist übrigens eine bodenlose Quelle wertvoller Informationen.
Mikeserv

1
Beachten Sie auch die settings=$(stty -g); stty raw; dd ...; stty "$settings", um die tty-Einstellungen zu speichern und wiederherzustellen.
Stephane Chazelas

@StephaneChezales - ich bin nicht an einem Computer - denkst du, dass die trBearbeitungssache auch funktionieren könnte?
Mikeserv

1
Nein, da trdie Ausgabe als Pipe gepuffert würde und Tastaturen außerhalb der USA Tasten haben, die Zeichen außerhalb des \1-\177Bereichs senden . ddist der idiomatische Weg hier.
Stephane Chazelas

2

Wenn Sie nur eine Schleife oder ein Skript anhalten müssen und anstelle einer beliebigen Taste die Eingabetaste drücken möchten, readerledigt dies die Aufgabe von alleine.

do_stuff
read
do_more_stuff

Es ist nicht endbenutzerfreundlich, kann aber in Fällen ausreichen, in denen Sie ein schnelles Skript für sich selbst schreiben und es anhalten müssen, um etwas manuell im Hintergrund zu tun.


Dies ist wahr, aber für die Datenbank ist es am hilfreichsten, ein Beispiel zu zeigen.
SDsolar

Danke, ich habe Ihren Rat an Bord genommen. Nur einen Befehlsnamen zu schreiben, ist im Nachhinein nicht sehr klar.
mwfearnley

1

Versuche dies:

function pause(){
   read -p "$*"
}

1
Kann jemand bitte erklären, warum dies abgelehnt wird? Ist es aus Mangel an Inhalten oder ist dies eine schlechte Lösung?
3ozän

4
@ 3ocene Dies zeigt nicht die Verwendung der erstellten Funktion. Außerdem fehlt jede Erklärung.
Parvus

Einverstanden. Können Sie bitte ein Beispiel zeigen, wie diese Funktion aufgerufen wird?
SDsolar

1

Diese Funktion funktioniert sowohl in bashals zshauch und stellt die E / A für das Terminal sicher:

# 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

Legen Sie es in Ihre .{ba,z}shrcfür große Gerechtigkeit!


0

Ja zur Verwendung read- und es gibt einige Verbesserungen, die es sowohl cronim Terminal als auch im Terminal am nützlichsten machen .

Beispiel:

time rsync (options)
read -n 120 -p "Press 'Enter' to continue..." ; echo " "

Mit dem -n 120 tritt nach 2 Minuten eine Zeitüberschreitung für die Leseanweisung auf, sodass sie nicht blockiert cron.

Im Terminal dauert es 2 Minuten, um zu sehen, wie lange die rsyncAusführung des Befehls gedauert hat.

Dann echowird die nachfolgende Bash-Eingabeaufforderung in der nächsten Zeile angezeigt.

Andernfalls wird es direkt nach "Weiter ..." in derselben Zeile angezeigt, wenn Enterim Terminal gedrückt wird.

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.