shell_exec()超时管理&exec()

Dav*_*ell 8 php shellexecute

我正在使用我编写的包装器类运行第三方脚本,该类调用shell_exec()和管道到我稍后使用PHP代码解析的文件中.我应该提到这是有效的,但是我正在尝试增强功能,遇到了一个我没想过的用例.

如何在shell_exec()上管理超时?我想把它包装成一个,try() catch()但我不知道如何最好地处理时间组件.

我一直在阅读这里有关的几个问题shell_exec(),exec()并且似乎通过将输出参数传递给exec()你可以得到一个返回,但这确实依赖于脚本以返回状态结束.再加上我的迷你测试页面,我似乎无法让它返回任何输出!

我想到的另一个选项是使用模态对话框,使用ajax样式微调器,同时使用它运行的脚本,并在javascript中设置手动超时.然后,它给用户一个关于它失败/超时和结束的模型对话框消息.

这个用例有没有可接受的方法?

我的迷你测试包括以下内容,

public $e_return = array();
public $e_status = '';
// Paths are absolute from /
public function execCheck($domain){
    exec($this->ssl_check_path." -s ".$domain." -p 443 > ".$this->folder.$this->filename." 2>&1 &", &$this->e_return, &$this->e_status);
}

// Returns
Array
(
)

0
Run Code Online (Sandbox Code Playgroud)

使用此问题作为ref, 无法使用PHP exec执行PHP脚本

http://www.php.net/manual/en/function.exec.php

Vla*_*oss 16

我为这样的任务写了一些工作代码.函数返回退出代码(0 - 确定,> 0 - 错误)并将stdout,stderr写入引用变量.

/*execute program and write all output to $out
terminate program if it runs more than 30 seconds */
execute("program --option", null, $out, $out, 30);
echo $out;

function execute($cmd, $stdin=null, &$stdout, &$stderr, $timeout=false)
{
    $pipes = array();
    $process = proc_open(
        $cmd,
        array(array('pipe','r'),array('pipe','w'),array('pipe','w')),
        $pipes
    );
    $start = time();
    $stdout = '';
    $stderr = '';

    if(is_resource($process))
    {
        stream_set_blocking($pipes[0], 0);
        stream_set_blocking($pipes[1], 0);
        stream_set_blocking($pipes[2], 0);
        fwrite($pipes[0], $stdin);
        fclose($pipes[0]);
    }

    while(is_resource($process))
    {
        //echo ".";
        $stdout .= stream_get_contents($pipes[1]);
        $stderr .= stream_get_contents($pipes[2]);

        if($timeout !== false && time() - $start > $timeout)
        {
            proc_terminate($process, 9);
            return 1;
        }

        $status = proc_get_status($process);
        if(!$status['running'])
        {
            fclose($pipes[1]);
            fclose($pipes[2]);
            proc_close($process);
            return $status['exitcode'];
        }

        usleep(100000);
    }

    return 1;
}
Run Code Online (Sandbox Code Playgroud)


Rya*_*ney 7

我建议你考虑使用proc_open.您可以将其配置为返回流资源,手动保留计时器,如果计时器在进程完成之前到期,则可以使用它来终止它proc_terminate.如果它在计时器到期之前完成,那么您可以使用proc_close然后stream_get_contents获取本来写入stdout的数据.

http://www.php.net/manual/en/function.proc-open.php

  • 我也发现这个问题很方便,http://stackoverflow.com/questions/2603912/php-set-timeout-for-script-with-system-call-set-time-limit-not-working (2认同)