Eu tenho um comando que desejo que seja executado novamente automaticamente sempre que ele terminar, então executei algo assim:
while [ 1 ]; do COMMAND; done;
mas se eu não conseguir parar o loop, Ctrl-cisso simplesmente mata COMMAND
e não o loop inteiro.
Como eu conseguiria algo semelhante, mas que posso parar sem precisar fechar o terminal?
Responder1
Você pode parar e colocar seu trabalho em segundo plano enquanto ele está em execução usando ctrl+ z. Então você pode matar seu trabalho com:
$ kill %1
Onde [1] é o número do seu trabalho.
Responder2
Verifique o status de saída do comando. Se o comando foi finalizado por um sinal o código de saída será 128 + o número do sinal. DeDocumentação online GNU para bash:
Para os propósitos do shell, um comando que sai com status de saída zero foi bem-sucedido. Um status de saída diferente de zero indica falha. Este esquema aparentemente contra-intuitivo é usado para que haja uma maneira bem definida de indicar o sucesso e uma variedade de maneiras de indicar vários modos de falha. Quando um comando termina em um sinal fatal cujo número é N, o Bash usa o valor 128+N como status de saída.
POSIX também especificaque o valor de um comando terminado por um sinal é maior que 128, mas não parece especificar seu valor exato como o GNU faz:
O status de saída de um comando que terminou porque recebeu um sinal deve ser reportado como maior que 128.
Por exemplo, se você interromper um comando com control-C o código de saída será 130, porque SIGINT é o sinal 2 em sistemas Unix. Então:
while [ 1 ]; do COMMAND; test $? -gt 128 && break; done
Responder3
Eu diria que seria melhor colocar seu loop infinito em um script e manipular os sinais lá. Aqui está umponto de partida básico. Tenho certeza que você desejará modificá-lo para se adequar. O script usa trap
para capturar ctrl- c(ou SIGTERM
), encerra o comando (usei sleep
aqui como teste) e sai.
cleanup ()
{
kill -s SIGTERM $!
exit 0
}
trap cleanup SIGINT SIGTERM
while [ 1 ]
do
sleep 60 &
wait $!
done
Responder4
Se você executar o bash, -e
ele sairá em qualquer condição de erro:
#!/bin/bash -e
false # returns 1
echo This won't be printed