如果程序在给定的超时内没有产生任何输出,如何杀死它?


2

我想检测一些进程何时被卡住,但它没有给我任何关于此事的线索。我所知道的是,如果它在给定的超时内没有产生任何输出(假设30秒),则意味着它可能被阻止。

我知道coreutils' timeout 程序,但它基于完整的程序退出时间,而不是最后一行输出时间。我喜欢这样的事情:

timeout --stdout --stderr 30s my-program

有没有办法做到这一点?我该怎么做?


我喜欢这个主意,但我不能指出现有的工具。这本身并不难。
tripleee

你可能会发现 这个 有用。
Wobbly

Answers:


1

代码

保存为 tkill (使其可执行并调整您的 PATH 如果需要的话):

#!/bin/bash

_terminate_children() {
        trap "exit 143" SIGTERM && kill -- -$$
}

trap _terminate_children SIGINT SIGTERM

tout="$1"
shift
eval $@ | tee >(while :; do
   read -t "$tout"
   case $? in
      0) : ;;
      1) break ;;
      *) _terminate_children ;;
   esac
done)
exit ${PIPESTATUS[0]}

基本用法

tkill 30 some_command

第一个论点( 30 这里是以秒为单位的超时。


笔记

  • tkill 预计 some_command 生成文本(非二进制)输出。
  • tkill 探头 stdout 给定命令。包括 stderr 像下面的最后一个高级示例中那样重定向它。

高级用法

这些是有效的例子:

tkill 9 foo -option value
tkill 9 "foo -option value"  # equivalent to the above
tkill 5 "foo | bar"
tkill 5 'foo | bar'
tkill 5 'foo | bar | baz'    # tkill monitors baz
tkill 5 'foo | bar' | baz    # baz reads from tkill
tkill 3 "foo; bar"
tkill 6 "foo && bar || baz"
tkill 7 "some_command 2>&1"

在这些引号中使用Bash语法。


退出状态

  • 如果 some_command 退出然后退出状态将被重新用作退出状态 tkill; tkill 5 true 回报 0; tkill 5 false 回报 1; tkill 5 "true; false" 回报 1
  • 如果给定的超时到期或 tkill 被打断了 SIGINT 要么 SIGTERM 然后退出状态将是 143

代码片段解释

  • eval 使高级示例成为可能。
  • tee 允许我们分析 stdin 同时仍将其副本传递给 stdout
  • read -t 负责应用超时,其退出状态用于确定下一步做什么。
  • 被监视的命令在需要时被杀死 这个解决方案
  • 使用检索监视命令的退出状态 这个解决方案

0

所以,基本上是这样的:

#!/bin/bash
tmp1=/tmp/tmp-$$-1
tmp2=/tmp/tmp-$$-2
touch $tmp1
touch $tmp2

time_out=30

typeset -i i

i=0
my-program > $tmp1 &
pgmpid=$!

while ps $pgmpid > /dev/null ; do
    sleep 1
    if diff $tmp1 $tmp2 > /dev/null ; then
        i=i+1
        if [ $i -gt $time_out ] ; then
            kill $pgmpid
        fi
    else
        i=0
        cp $tmp1 $tmp2 
    fi
done

rm -f $tmp1 $tmp2

这应该可以解决问题,虽然我期待一些有线的TBH ......不管怎样,谢谢!
Yajo

0

在将输出复制到文件的同时在后台运行该程序。 30秒后,如果文件为空,则终止程序,否则将其恢复到前台。

my-program | tee temp-file & 
sleep 30
[ -s temp-file ] && kill $! || fg $!

有了这个,如果在30秒后它变得冻结,你运气不好吧?
Yajo

是啊。似乎我误解了这个问题。
Lubo Kanev
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.