Answers:
使用zsh
,您可以执行以下操作:
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
这个想法是使用带有超时的输出读取-t
选项。sysread
your-command
请注意,它使your-command
的输出成为管道。可能是因为your-command
它没有进入终端时才开始缓冲其输出,在这种情况下,您可能会发现它有一段时间没有输出任何东西,但这仅是由于该缓冲,而不是因为它被某种方式挂起了。
您可以通过使用stdbuf -oL your-command
还原行缓冲(如果您的命令使用stdio)或使用zpty
而不是coproc
伪造终端输出来解决此问题。
使用bash
,您必须依靠dd
和GNU(timeout
如果可用):
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
除了coproc
,您还可以使用流程替换:
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)
(这将无法在其中工作,zsh
或者ksh93
因为其中$!
不包含pid your-command
)。