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 ).