这回答命令行命令自动杀死一个命令后,一定的时间

建议使用1行方法使bash命令行中运行的命令超时:

( /path/to/slow command with options ) & sleep 5 ; kill $!

但是,给定的“长时间运行”命令可能会在超时之前完成。 (让我们称它为“通常运行时间长但有时很快”的命令,或者简称为tlrbsf。)

所以这个漂亮的一行方法有几个问题。 首先,睡眠不是有条件的,因此在序列完成所花费的时间上设置了一个不希望的下界。当tlrbsf命令在2秒内完成时,考虑30秒或2m甚至5m的睡眠时间——这是非常不可取的。 其次,kill是无条件的,因此该序列将尝试kill一个未运行的进程并抱怨它。

所以…

是否有一种方法可以超时一个典型的长时间运行但有时快速(“tlrbsf”)命令

有一个bash实现(另一个问题已经有Perl和C的答案) 将终止在较早的两个:TLRBSF程序终止,或超时过去 不会杀死不存在/不运行的进程(或者,可选:不会抱怨失败的杀死) 不一定非要是一行字 可以在Cygwin或Linux下运行吗

... 还有,为了加分

在前台运行TLRBSF命令 任何“睡眠”或额外的进程在后台

这样,TLRBSF命令的stdin/stdout/stderr可以重定向,就像它已经直接运行吗?

如果是,请分享你的代码。如果不是,请解释原因。

我花了一段时间试图破解前面提到的例子,但我的bash技能达到了极限。


当前回答

我有一个cron工作,调用一个php脚本,有时,它会卡在php脚本。这个解决方案对我来说是完美的。

我使用:

scripttimeout -t 60 /script.php

其他回答

使用实例在1秒后使slows命令超时。

timeout 1 || echo "I failed, maybe due to timeout "

要确定命令是否超时或由于自身原因失败,请检查状态代码是否为124:

# ping the address 8.8.8.8 for 3 seconds, but timeout after only 1 second
timeout 1 ping 8.8.8.8 -w3
EXIT_STATUS=$?
if [ $EXIT_STATUS -eq 124 ]
then
echo 'Process Timed Out!'
else
echo 'Process did not timeout. Something else went wrong.'
fi
exit $EXIT_STATUS

注意,当退出状态为124时,您不知道它是由于您的timeout命令而超时,还是命令本身由于它自己的一些内部超时逻辑而终止,然后返回124。不过,在这两种情况下,您都可以安全地假设发生了某种超时。

另请参阅http://www.pixelbeat.org/scripts/timeout脚本,其功能已集成到更新的coreutils中

timeout命令本身有一个——前台选项。这使得命令“在不直接从shell提示符运行超时时”与用户交互。

timeout --foreground the_command its_options

我认为提问者一定知道timeout命令的非常明显的解决方案,但出于这个原因,他要求另一种解决方案。超时没有为我工作时,我调用它使用popen,即。“不是直接从壳里取的。”然而,我不认为这就是提问者的原因。看看它的手册页。

如果您已经知道要在超时后终止的程序(假设是程序)的名称(例如3秒),我可以提供一个简单但有点脏的替代解决方案:

(sleep 3 && killall program) & ./program

如果我用系统调用来调用基准测试进程,这将非常有效。

OS X还没有使用bash 4,也没有/usr/bin/timeout,所以这里有一个在OS X上工作的函数,没有自制或macports,类似于/usr/bin/timeout(基于Tino的回答)。参数验证、帮助、使用和对其他信号的支持是读者的练习。

# implement /usr/bin/timeout only if it doesn't exist
[ -n "$(type -p timeout 2>&1)" ] || function timeout { (
    set -m +b
    sleep "$1" &
    SPID=${!}
    ("${@:2}"; RETVAL=$?; kill ${SPID}; exit $RETVAL) &
    CPID=${!}
    wait %1
    SLEEPRETVAL=$?
    if [ $SLEEPRETVAL -eq 0 ] && kill ${CPID} >/dev/null 2>&1 ; then
      RETVAL=124
      # When you need to make sure it dies
      #(sleep 1; kill -9 ${CPID} >/dev/null 2>&1)&
      wait %2
    else
      wait %2
      RETVAL=$?
    fi
    return $RETVAL
) }