Qual è l'equivalente di Linux alla pausa DOS?


236

Ho uno script di shell Bash in cui vorrei mettere in pausa l'esecuzione fino a quando l'utente preme un tasto. In DOS, questo è facilmente realizzabile con il comando "pause". Esiste un equivalente Linux che posso usare nel mio script?

Risposte:


329

read fa questo:

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

I -n1specifica che attende solo per un singolo carattere. Lo -rmette in modalità raw, che è necessario perché altrimenti, se si preme qualcosa come barra rovesciata, non si registra fino a quando non si preme il tasto successivo. I -pspecifica la richiesta, che deve essere citato se contiene spazi. L' keyargomento è necessario solo se vuoi sapere quale tasto hanno premuto, nel qual caso puoi accedervi $key.

Se stai usando Bash, puoi anche specificare un timeout con -t, che fa sì che read non restituisca un errore quando non viene premuto un tasto. Quindi per esempio:

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
A rigor di termini, sarebbe "Enter any non-NUL character to continue". Alcuni tasti non inviano alcun carattere (come Ctrl...) e alcuni ne inviano più di uno (come F1, Home...). bashignora i caratteri NUL.
Stephane Chazelas,

2
Di solito è una buona idea chiedere una chiave specifica come enter, spazio o Y. "QUALSIASI" può essere fonte di confusione per alcuni utenti, c'è una chiave TAB quindi perché nessuna chiave ANY e sicuramente ci sono chiavi potenzialmente pericolose come ESCAPE, CTRL, CMD, il pulsante di accensione, ecc. Questo non è più così rilevante oggi, perché al giorno d'oggi la console è di solito utilizzata solo da utenti esperti che interpretano correttamente "QUALSIASI chiave". Il Manuale di progettazione di Apple 2, piuttosto vecchio, ha un'interessante sezione dedicata a questo argomento ( apple2scans.net/files/1982-A2F2116-m-a2e-aiiedg.pdf ).
Gellweiler,

3
Se invece usi il messaggio, Press a key to continue...anche gli utenti meno esperti potranno trovare il atasto e premerlo; o)
DJDaveMark,

1
Ciò avrà problemi con command | myscript.sho myscript.sh | command. Vedi questa risposta per una soluzione.
Tom Hale,

Se qualcuno ottiene read: 1: read: Illegal option -nassicurarsi di avvolgere il comando in bash -c 'command && command'ecc. Poiché è probabile che l'errore sia sh. Lo sto facendo in un comando wrapper Lando.
Elijah Lynn,

155

Uso questi modi molto brevi, che sono come le soluzioni @theunamedguy e @Jim, ma con timeout e modalità silenziosa in aggiunta.

In particolare, adoro l'ultimo caso e lo uso in molti script eseguiti in un ciclo fino a quando l'utente preme Enter.

comandi

  • Inserisci la soluzione

    read -rsp $'Press enter to continue...\n'
  • Soluzione di escape (con -d $ '\ e')

    read -rsp $'Press escape to continue...\n' -d $'\e'
  • Qualsiasi soluzione chiave (con -n 1)

    read -rsp $'Press any key to continue...\n' -n 1 key
    # echo $key
    
  • Domanda con scelta preselezionata (con -ei $ 'Y')

    read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;
    # echo $key
    
  • Soluzione di timeout (con -t 5)

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

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

Spiegazione

-r specifica la modalità raw, che non consente caratteri combinati come "\" o "^".

-s specifica la modalità silenziosa e perché non abbiamo bisogno dell'output della tastiera.

-p $ ' prompt ' specifica il prompt, che deve essere compreso tra $ 'e' per lasciare spazi e caratteri di escape. Fai attenzione, devi mettere tra virgolette singole con il simbolo di dollari per beneficiare dei caratteri di escape, altrimenti puoi usare le virgolette semplici.

-d $ ' \ e ' specifica l'escape come carattere delimitatore, quindi come carattere finale per la voce corrente, è possibile inserire qualsiasi carattere, ma fai attenzione a inserire un carattere che l'utente può digitare.

-n 1 specifica che necessita solo di un singolo carattere.

-e specifica la modalità readline.

-i $ ' Y ' specifica Y come testo iniziale in modalità readline.

-t 5 specifica un timeout di 5 secondi

tasto serve nel caso in cui sia necessario conoscere l'input, nel caso -n1, il tasto che è stato premuto.

$? serve a conoscere il codice di uscita dell'ultimo programma, per leggere, 142 in caso di timeout, 0 input corretto. Metti $? in una variabile il prima possibile se è necessario testarlo dopo alcuni comandi, perché tutti i comandi riscriverebbero $?


1
+1 per la spiegazione -s; man reade l' read --helpaiuto non ha aiutato su Ubuntu 10.04.1 LTS. Modifica: help readdid; il resto è deprecato?
Cees Timmerman,

1
1+ per la grande spiegazione: ma ho ottenuto read: -i: invalid optionper l'ex. read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;su #osx invece read -rp $'kill-server: Are you sure (Y/n) : ' -d $'Y' key;funziona per me. `
Tino Rüb,

Non so come funziona su OSX ma ho fatto alcuni test e -ifunziona perfettamente su Ubuntu, inoltre non so come -dfunziona allo stesso modo su OSX.
y.petremann,

si può aggirare il prompt davvero in modo rapido e piacevole usando un'eco prima di leggere, eventualmente echo -n
THororcerer

15

readsenza parametri continuerà solo se premi invio. Il pausecomando DOS continuerà se si preme un tasto qualsiasi. Utilizzare read –n1se si desidera questo comportamento.


15

Questo ha funzionato per me su molteplici versioni di Linux, dove alcune di queste altre soluzioni non lo hanno fatto (comprese le più popolari qui). Penso che sia anche più leggibile ...

echo Press enter to continue; read dummy;

Si noti che una variabile deve essere fornita come argomento a read.


questa risposta risolve il mio problema, se copio e incollo questa riga e per qualche motivo ho aggiunto più righe, le righe aggiunte non vengono eseguite, come nel caso della pausa DOS
Sérgio,

10

read -n1non è portatile. Un modo portatile per fare lo stesso potrebbe essere:

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

Oltre ad usare read, basta solo premere ENTERper continuare a richiedere:

sed -n q </dev/tty

2
status=nonenon è neanche portatile. Reindirizzare invece stdout e stderr su / dev / null. read -r line < /dev/ttysarebbe abbastanza per premere ENTER ... .
Stephane Chazelas,

@StephaneChezales grazie - non lo sapevo. ora lo risolverò. Grazie ancora - risolto. A proposito, sei un pozzo senza fondo di informazioni utili.
Mikeserv,

1
Si noti inoltre che settings=$(stty -g); stty raw; dd ...; stty "$settings"per salvare e ripristinare le impostazioni tty.
Stephane Chazelas,

@StephaneChezales - non sono su un computer - pensi che anche la trmodifica potrebbe funzionare?
Mikeserv,

1
No, perché trbufferizzerebbe il suo output come una pipe, e le tastiere non statunitensi hanno tasti che inviano caratteri al di fuori \1-\177dell'intervallo. ddè il modo idiomatico qui.
Stephane Chazelas,

2

Se hai solo bisogno di mettere in pausa un ciclo o uno script e sei felice di premere Invio invece di qualsiasi tasto, allora readfarà da solo il lavoro.

do_stuff
read
do_more_stuff

Non è facile per l'utente finale, ma potrebbe essere sufficiente nei casi in cui stai scrivendo uno script rapido per te stesso e devi metterlo in pausa per fare qualcosa manualmente in background.


Questo è vero, ma per il database è molto utile mostrare un esempio.
SDsolar,

Grazie, ho preso il tuo consiglio a bordo. Scrivere semplicemente un nome di comando non è molto chiaro col senno di poi.
mwfearnley,

1

Prova questo:

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

1
Qualcuno può spiegare perché questo è downvoted? È per mancanza di contenuti o è una cattiva soluzione?
3ocene,

4
@ 3ocene Questo non mostra l'utilizzo della funzione creata; inoltre questa mancanza di spiegazioni.
parvus,

Concordato. Potete per favore mostrare un esempio di come viene invocata questa funzione?
SDsolar

1

Questa funzione è disponibile in entrambi bashe zsh, e assicura l'I / O al terminale:

# 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

Mettilo nel tuo .{ba,z}shrcper la Grande Giustizia!


0

Sì all'utilizzo read- e ci sono un paio di modifiche che lo rendono più utile in entrambi crone nel terminale.

Esempio:

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

-N 120 fa scadere l'istruzione read dopo 2 minuti, quindi non si blocca cron.

Nel terminale ci vogliono 2 minuti per vedere quanto tempo ha richiesto l' rsyncesecuzione del comando.

Quindi il successivo echoè così che il successivo prompt bash apparirà sulla riga successiva.

Altrimenti verrà mostrato sulla stessa riga direttamente dopo "continua ..." quando Enterviene premuto nel terminale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.