如果某个进程安静了一段时间,则杀死该进程

Ben*_*ojo 9 linux shell bash timeout stdout

我有一个实用程序,它有一个讨厌的习惯,那就是安静并呆在那里,我已经知道它在这个过程中做了多长时间,所以我用它timeout来对抗它,但有时它会在那之前这样做。timeout如果停止将输出定向到标准输出,是否有类似的工具会终止进程?

Sté*_*las 8

使用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选项sysreadyour-command超时的输出中读取。

请注意,它使your-command的输出成为管道。可能是your-command当它没有进入终端时开始缓冲它的输出,在这种情况下你可能会发现它在一段时间内没有输出任何东西,但这只是因为缓冲,而不是因为它以某种方式挂起

您可以通过使用stdbuf -oL your-command来恢复行缓冲(如果您的命令使用 stdio)或使用zpty而不是coproc伪造终端输出来解决这个问题。

使用bash,您必须依赖ddGNU(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)

(这将不起作用zshksh93因为$!不包含your-command那里的 pid )。