【问题标题】:Limit execution time of shell_script in PHP限制 PHP 中 shell_script 的执行时间
【发布时间】:2012-07-16 20:52:00
【问题描述】:

我正在使用 PHP 脚本在 Linux 中调用 shell 脚本,我执行以下操作:

shell_exec('./shell_script.sh');

此后,PHP 脚本继续运行。所有这些都按预期工作。

但是,有时 shell_script 出于某种原因没有完成执行,所以这里有一个问题:

shell_script.sh 执行 x 时间后如何终止? 应该以某种方式在 PHP 本身中处理这件事(在这种情况下不认为这是可能的)还是应该在 .sh 本身中完成?

所以就在:

#!/bin/bash

在 .sh 的开头,如果执行时间超过 20 秒,我可以放什么让它终止吗?

【问题讨论】:

    标签: php linux shell shell-exec


    【解决方案1】:

    我不知道你是否可以在php中做到这一点,并且bash中可能存在更好的解决方案,但这是你可以做到的:

    这是您可以紧跟在#!/bin/bash 之后的行,以在 20 秒后终止当前脚本:

    (sleep 20 && kill $$) &
    

    bash 将 $$ 替换为当前脚本的 pid。

    【讨论】:

    • 要让它在同一个脚本中工作,你可以启动一个子shell:( sleep 20 && kill $$ ) &
    • 是的,这行得通。我以为我已经尝试过了,但显然我没有,因为现在它可以工作了......我将编辑我的答案
    • 似乎无法完全工作,因为它无法获得正确的 pid?例如第 3 行:kill: (32613) - 没有这样的进程
    • 另外,这种方法的问题是脚本现在总是需要 20 秒才能死掉,而不是如果先完成则在 8 秒后死掉......嗯。
    • @hsmoore.com 当父进程在sleep 完成之前退出时,会发生“没有这样的进程”。您可以通过将子shell 的stderr 重定向到/dev/null 来消除该消息。要使脚本更快地终止,您可以通过存储 PID 并稍后将其终止来取消计时器。其实我会用代码示例添加答案...
    【解决方案2】:

    你可以这样使用:

    # start timer
    ( sleep $TIMEOUT ; kill $$ ) 2>/dev/null &
    TIMER_PID=$!
    
    # "payload"
    echo hello
    
    # cancel timer
    kill $TIMER_PID
    

    YMMV 但是,在我的测试中,应该取消计时器的部分有时不会杀死 sleep,并且程序会一直等到超时结束。

    【讨论】:

    • 我已经尝试过这种方法,但效果并不好,因为它不会杀死子进程,只会杀死主 shell_script。 shell_script 基本上使用 xvfb-run 来运行 x 应用程序。所以基本上 kill $TIMER_PID 也应该杀死 bash 的所有子进程。有意义吗?
    猜你喜欢
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多