Como faço para interromper um script bash até que um usuário pressione Espaço ?
Gostaria de colocar a questão em meu script
Pressione espaço para continuar ou CTRL + C para sair
e então o script deve parar e aguardar até que a barra de espaço seja pressionada.
Comentários
- Tudo isso e muito mais é abordado neste SO Q & A BTW: Qual é o equivalente do Linux para fazer uma pausa no DOS?
- Veja também: Pausar o script Shell até pressionar Enter no loop while
- relacionado: unix.stackexchange.com/questions/293940/…
Resposta
Você pode usar 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
Substitua " "
para o espaço acima por ""
para a tecla Enter, $"\t"
para a tecla Tab.
Comentários
- Você deve adicionar -s para não imprimir o caractere pressionado no terminal. E adicione uma quebra de linha no final, ou a saída continuará diretamente na mesma linha da pergunta. O melhor seria:
read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
- Este script não ‘ não funciona. Acabei de testar no Linux Red Hat … O bloco
else
sempre é executado, mesmo quando a barra de espaço é pressionada. - @robert It ‘ s porque você não ‘ t usa
bash
. Funciona se você usarread _
em vez disso, se tiver algum outro shell que não sejabash
. - O
''
contém um espaço dentro? - Isso é lido de STDIN, o que causará problemas fornecidos
pipeline | script.sh
Consulte esta resposta para uma solução.
Resposta
O método discutido neste SO Q & A é provavelmente o melhor candidato para uma alternativa ao pause
comportamento ao qual você “está acostumado no Windows quando fazendo arquivos BAT.
$ read -rsp $"Press any key to continue...\n" -n1 key
Exemplo
Aqui estou executando o acima e simplesmente pressionando qualquer tecla, neste caso o Tecla D .
$ read -rsp $"Press any key to continue...\n" -n1 key Press any key to continue... $
Referências
Comentários
- Quero dizer, por que
$
antes re a string aqui:-rsp $'Press
? - @ rubo77 – ah. É assim ‘ como você pode fazer uma string literal com caracteres especiais. É ‘ s da forma: $ ‘ … ‘
- @ rubo77 – isso ‘ é diferente. Isso ‘ é um cifrão com aspas duplas, usei um dólar com aspas simples. Exclua esse comentário, ele ‘ está errado.
- Ah, entendo. No caso de você colocar sequências de escape dentro da string de prompt. consulte wiki.bash-hackers.org/syntax/quoting#ansi_c_like_strings
- @ rubo77 – sim, essa notação permite que sequências de escape sejam incluídas sem quaisquer linhas
echo -e "..."
extras. É ‘ muito mais compacto nessas situações.
Resposta
Você poderia criar uma função para ele:
pause(){ read -n1 -rsp $"Press any key to continue or Ctrl+C to exit...\n" }
Então você pode usar isso em qualquer lugar em seu script:
pause
Comentários
- se você for novo no shell scripting – você precisa colocar a função no topo do seu script antes de usá-lo
Resposta
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"
Isso agora imprime um prompt sem uma nova linha final, lida com CTRL+C
de maneira confiável, invoca stty
com a freqüência necessária e restaura o tty de controle exatamente no estado em que stty
encontrou. Procure em man stty
informações sobre como controlar explicitamente os ecos, os caracteres de controle e tudo.
Você também pode fazer isso:
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
Você poderia fazer isso com ENTER
, sem [
testes ]
e nenhum stty
como:
sed -n q </dev/tty
Comentários
- Suas duas últimas soluções parecem funcionar bem com
/bin/sh
(por exemplo, no FreeBSD) também, não apenas com o bash. - sua resposta é SO equivalente ou ainda melhor?
Resposta
Aqui “uma maneira que funciona em ambos bash
e zsh
, e garante I / O para o 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
Coloque em seu .{ba,z}shrc
pela Grande Justiça!
Resposta
preguiçoso um liner:
echo "Press any key to continue or Ctrl+C to cancel" read && do_something.sh
a desvantagem é que você perde o controle quando o usuário pressiona ctrl + c. O script sempre sairá com o código 130 nesse caso.
Resposta
Configurações IFS
para a string vazia suprime o comportamento padrão de leitura de corte de espaço em branco.
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
ATUALIZAÇÃO 23/05/2018: podemos simplificar isso usando a variável REPLY, que não está sujeita à divisão de palavras:
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
Resposta
Aqui “uma solução simples de Pressione ESPAÇO para continuar (não ENTER)
read -s -d " "
Isso irá esperar até que você pressione a barra de espaço. Sim, apenas a barra de espaço, não quebraria se você pressionasse Enter.