Com zsh
, você pode fazer:
zmodload zsh/system
coproc your-command
while :; do
sysread -t 10 -o 1 <&p && continue
if (( $? == 4 )); then
echo "Timeout" >&2
kill $!
fi
break
done
A ideia é usar a -t
opção de sysread
ler da your-command
saída com um tempo limite.
Observe que ele faz your-command
da saída um tubo. Pode ser que your-command
comece a armazenar em buffer sua saída quando ele não for para um terminal; nesse caso, você poderá descobrir que não produz nada há algum tempo, mas apenas por causa desse buffer, não porque está travado de alguma forma.
Você pode contornar isso usando stdbuf -oL your-command
para restaurar o buffer de linha (se o seu comando usa stdio) ou usar em zpty
vez de coproc
falsificar uma saída do terminal.
Com bash
, você precisaria confiar no dd
GNU, timeout
se disponível:
coproc your-command
while :; do
timeout 10 dd bs=8192 count=1 2> /dev/null <&${COPROC[0]} && continue
if (($? == 124)); then
echo Timeout >&2
kill "$!"
fi
done
Em vez de coproc
, você também pode usar a substituição de processo:
while :; do
timeout 10 dd bs=8192 count=1 2> /dev/null <&3 && continue
if (($? == 124)); then
echo Timeout >&2
kill "$!"
fi
done 3< <(your-command)
(que não funcionará zsh
ou ksh93
porque $!
não contém o pid de your-command
lá).
Eu redirecionaria STDOUT para um arquivo e usaria o teste de carimbo de data / hora do monit para reiniciar o processo se o mtime do arquivo for maior que um limite.
fonte