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