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 -topção de sysreadler da your-commandsaída com um tempo limite.
Observe que ele faz your-commandda saída um tubo. Pode ser que your-commandcomece 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-commandpara restaurar o buffer de linha (se o seu comando usa stdio) ou usar em zptyvez de coprocfalsificar uma saída do terminal.
Com bash, você precisaria confiar no ddGNU, timeoutse 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á zshou ksh93porque $!não contém o pid de your-commandlá).