Quebrar loop infinito 'while' no FreeBSD

0

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?

    
por Harald Nordgren 08.02.2017 / 17:29

3 respostas

1

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.

    
por 08.02.2017 / 17:35
0

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
}
    
por 08.02.2017 / 18:32
0

Você já pensou em usar uma armadilha?

#! /bin/sh
trap "break" INT
while :
do
    COMMAND && sleep 15
done
    
por 08.02.2017 / 17:54