Adicione uma condição de morte:
canary=$(mktemp)
echo "Canary is $canary"
while [[ -f "$canary" ]]; do
COMMAND
sleep 15
done &
Para quebrar, mate ( rm
) o canário.
Eu tenho um sistema barebones FreeBSD
com apenas um terminal. Gostaria de monitorar zpool status
a cada 15 segundos ou mais. Normalmente, em sistemas "regulares" eu usaria watch -n15
, mas isso não está disponível aqui.
Não sei se quero instalar novos programas em um host frágil importante e possível. Mas estou aberto para fazê-lo se for realmente simples, ouvi falar de um substituto chamado cmdwatch
.
Minha solução simples para monitorar o programa é usar um loop while, a saber:
while :; do zpool status && sleep 15; done
Este trabalho ostensivo. No entanto, agora eu não posso quebrar o loop usando Ctrl + C, que é um grande incômodo. Eu posso usar Ctrl + Z para colocar o loop em segundo plano, chamar ps
para obter o PID e, em seguida, kill -9
do programa. Morte regular não funciona.
Então isso não é bom o suficiente. Para qualquer usuário que não seja eu, o sistema parece estar quebrado. Outro post me apontou para verificar se o código de retorno é maior que 128, SIGINT
deveria dar 130, assim
while [ 1 ]; do zpool status; test $? -gt 128 && break; done
Isso funciona se eu executar somente o comando sleep 15
. Encadear mais comandos juntos com ;
ou &&
fornece a situação antiga em que não posso interromper o loop.
O que eu faço?
Adicione uma condição de morte:
canary=$(mktemp)
echo "Canary is $canary"
while [[ -f "$canary" ]]; do
COMMAND
sleep 15
done &
Para quebrar, mate ( rm
) o canário.
O utilitário watch
do GNU está disponível para o FreeBSD como o gnu-watch
port / pacote .
Depois de colocar o loop em segundo plano, apenas fg
e pressione Ctrl + C .
bash-4.4$ while true; do echo hello && sleep 2; done &
[1] 26130
bash-4.4$ hello
hello
hello
hello
hello
hello
bash-4.4$ fg
while true; do
echo hello && sleep 2;
done
hello
^C
bash-4.4$
Uma implementação realmente simples do utilitário watch
com um tempo de espera estático de 5 segundos como uma função de shell:
function watch
{
while true; do
clear
command "$@"
sleep 5
done
}
Você já pensou em usar uma armadilha?
#! /bin/sh
trap "break" INT
while :
do
COMMAND && sleep 15
done