Come faccio a interrompere uno script bash finché un utente non ha premuto Spazio ?
Vorrei inserire la domanda nel mio script
Premi lo spazio per continuare o CTRL + C per uscire
, quindi lo script dovrebbe interrompersi e attendere che venga premuto lo spazio.
Commenti
- Tutto questo e molto altro è affrontato in questo SO Q & A BTW: Qual è lequivalente Linux alla pausa DOS?
- Vedi anche: Metti in pausa lo script della shell finché non premi Invio nel ciclo while
- correlati: unix.stackexchange.com/questions/293940/…
Risposta
Puoi utilizzare read
:
read -n1 -s -r -p $"Press space to continue...\n" 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
Sostituisci " "
per lo spazio sopra con ""
per il tasto Invio, $"\t"
per il tasto Tab.
Commenti
Risposta
Il metodo discusso in questo SO Q & A è probabilmente il miglior candidato per unalternativa al comportamento pause
a cui sei abituato su Windows quando facendo file BAT.
$ read -rsp $"Press any key to continue...\n" -n1 key
Esempio
Qui sto eseguendo quanto sopra e poi semplicemente premendo un tasto qualsiasi, in questo caso il D chiave.
$ read -rsp $"Press any key to continue...\n" -n1 key Press any key to continue... $
Riferimenti
Commenti
- Voglio dire perché
$
befo re la stringa qui:-rsp $'Press
? - @ rubo77 – ah. Questo è ‘ come puoi creare una stringa letterale con caratteri speciali. È ‘ nel formato: $ ‘ … ‘
- @ rubo77: ‘ è diverso. Quello ‘ è un segno di dollaro con virgolette doppie, ho usato un dollaro con virgolette singole. Elimina il commento, ‘ è sbagliato.
- Ah, ho capito. Nel caso in cui metti sequenze con escape allinterno della stringa di prompt. vedi wiki.bash-hackers.org/syntax/quoting#ansi_c_like_strings
- @ rubo77 – sì, la notazione consente di includere sequenze di escape senza
echo -e "..."
righe aggiuntive. ‘ è molto più compatto in quelle situazioni.
Risposta
Potresti creare una funzione per esso:
pause(){ read -n1 -rsp $"Press any key to continue or Ctrl+C to exit...\n" }
Quindi puoi usarlo ovunque nel tuo script:
pause
Commenti
- se non conosci lo scripting di shell, devi mettere la funzione allinizio dello script prima di usarlo
Risposta
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"
Ora stampa un prompt senza una nuova riga finale, gestisce CTRL+C
in modo affidabile, richiama stty
solo ogniqualvolta sia necessario e ripristina la tty di controllo esattamente nello stato in cui stty
trovato. Consulta man stty
per informazioni su come controllare esplicitamente gli echi, i caratteri di controllo e tutto il resto.
Potresti anche fare questo:
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
Potresti farlo con ENTER
, senza [
test ]
e nessun stty
mi piace:
sed -n q </dev/tty
Commenti
- Le tue ultime due soluzioni sembrano funzionare bene anche con
/bin/sh
(ad esempio su FreeBSD), non solo con bash. - è la tua risposta su SO equivalente o addirittura migliore?
Risposta
Ecco “un modo che funziona in entrambi bash
e zsh
e garantisce lI / 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
Inseriscilo nel tuo .{ba,z}shrc
per Great Justice!
Answer
lazy one liner:
echo "Press any key to continue or Ctrl+C to cancel" read && do_something.sh
lo svantaggio è che perdi il controllo quando lutente preme ctrl + c. In tal caso lo script uscirà sempre con il codice 130.
Risposta
Le impostazioni IFS
su stringa vuota sopprimono il comportamento predefinito di lettura di tagliare gli spazi vuoti.
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
AGGIORNAMENTO 23/05/2018: possiamo semplificarlo utilizzando la variabile REPLY, che non è soggetta a suddivisione in parole:
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
Rispondi
Ecco “una semplice soluzione da Premi SPAZIO per continuare (non INVIO)
read -s -d " "
Questo aspetterà finché non premi la barra spaziatrice. Sì, solo la barra spaziatrice, non si spezzerebbe se si preme Invio.
read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
else
viene eseguito sempre, anche quando si preme la barra spaziatrice.bash
. Funziona se utilizziread _
, se hai una shell diversa dabash
.''
contiene uno spazio allinterno?pipeline | script.sh
Vedi questa risposta per una soluzione.