Com zsh
, você poderia 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 opção -t
de sysread
para ler a partir de your-command
output com um tempo limite.
Note que isso faz com que your-command
seja um pipe. Pode ser que your-command
comece a armazenar em buffer sua saída quando ela não vai para um terminal, caso em que você pode descobrir que não produz nada em algum momento, mas apenas por causa desse buffer, não porque é pendurou de alguma forma.
Você poderia contornar isso usando stdbuf -oL your-command
para restaurar o buffer de linha (se o seu comando usar stdio) ou usar zpty
em vez de coproc
para falsificar uma saída de terminal.
Com bash
, você deve confiar em dd
e 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 processos:
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)
(isso não funcionará em zsh
ou ksh93
porque $!
não contém o pid de your-command
).