使用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
Run Code Online (Sandbox Code Playgroud)
这个想法是使用-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
Run Code Online (Sandbox Code Playgroud)
除了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)
Run Code Online (Sandbox Code Playgroud)
(这将不起作用zsh
或ksh93
因为$!
不包含your-command
那里的 pid )。