从PHP运行时没有任何输出

问题描述:

我一直在努力exec(),当我使用at Unix系统命令添加任务时,试图从中捕获输出.我的问题是,从脚本运行时没有任何输出,但是在交互模式下从终端 PHP运行它会输出几行.

I've been wrestling with exec(), trying to capture the output from it when I add a task using the at Unix system command. My problem is that it is giving no output when run from my script, however running it from the terminal and PHP in interactive mode prints out a couple of lines.

我要执行的命令是这样:

The command I want to execute is this:

echo exec("echo 'php -f /path/to/file.php foo=1' | at now + 1 minutes", $result);

var_dump()给出string(0) "",而print_r()吐出Array ().我尝试使用shell_exec(),它输出NULL,但是在网页上下文中运行时,以下输出hi:

var_dump() gives string(0) "", and print_r() spits out Array (). I've tried using shell_exec(), which outputs NULL, however the following outputs hi when run in a web page context:

echo exec("echo 'hi'");

这还会输出内容:

echo exec("atq");

但是,一旦我使用at,就什么也没有输出.我如何获得以下输出:

However, as soon as I use at, nothing is output. How can I get the output of:

exec("echo 'php -f /path/to/file.php foo=1' | at now + 1 minutes", $result);

因为目前,当PHP通过Apache以正常"方式运行时,它什么也没输出,但是在终端以及PHP的交互式控制台中运行该命令可以得到类似以下结果的预期结果:

Because at present it outputs nothing when run as "normal" by PHP through Apache, however running the command in the terminal as well as in PHP's interactive console gives me the expected result of something like:

php > echo exec("echo 'php -f /path/to/file.php foo=1' | at now + 1 minutes", $result);
warning: commands will be executed using /bin/sh
job 1219 at Sun Jun 10 12:43:00 2012

safe_mode已关闭,我无法弄清楚为什么在执行atq或任何其他受exec()赞扬的命令时,我无法通过管道式echo语句从at获得任何输出.我已经搜索并阅读了此问题,全部无济于事.

safe_mode is off, and I cannot work out why I don't get any output from at with a piped-in echo statement, when executing atq or any other commend with exec() gives me output. I've searched and read this question, all to no avail.

如果在exec()中使用第二个参数,如何获取exec()at的输出返回到字符串或数组?

How can I get exec() to return the output from at to either a string, or an array if using a second argument with exec()?

有效的一线解决方案

我没有意识到这可能是如此简单.只需将2>&1放在要执行的命令的末尾,即可将stderr重新路由到stdout.现在,at的所有输出都将打印到stdout,因此由exec()捕获:

Working, one line solution

I didn't realise it could be this simple. All that is required is to reroute stderr to stdout by putting 2>&1 at the end of the command to execute. Now any output from at is printed to stdout, therefore captured by exec():

echo exec("echo 'php -f /path/to/file.php foo=1' | at now + 1 minutes 2>&1", $result);


我的旧解决方案:

我试图保持一线/两线解决方案,但是最后唯一可行的方法是使用proc_open() ,因为at记录到stderr,而exec()却看不到! 我要感谢@Tourniquet指出了这一点,但是他删除了答案.引用:


My old solution:

I was trying to keep to a one/two line solution, however the only thing that worked in the end was using proc_open() because at logs to stderr, which exec() doesn't read! I'd like to thank @Tourniquet for pointing this out, however he has deleted his answer. To quote:

据我所见,在stderr的输出中,它没有被捕获 执行我对此没有真正的信心,但可以考虑使用 http://php.net/manual/en/function.proc-open.php ,这使您能够 将stderr定向到其自己的管道.

As far as i can see, at outputs to stderr, which isn't captured by exec. I'm not really confident in it, but consider using http://php.net/manual/en/function.proc-open.php, which allows you to direct stderr to its own pipe.

这实际上是正确的处理方式.我的解决方案(因为我只想要stderr)是这样做的:

This is actually the correct way of doing things. My solution (because I only want stderr) was to do this:

// Open process to run `at` command
$process = proc_open("echo 'php -f /path/to/file.php foo=1' | at now + 1 minutes", array(2 => array("pipe", "w")), $pipes);

// Get stuff from stderr, because `at` prints out there for some odd reason
if(is_resource($process)) {
    $output = stream_get_contents($pipes[2], 100);
    fclose($pipes[2]);

    $return_value = proc_close($process);
}

$output现在包含打印到stderr的所有at(由于这不是错误,因此应实际转至stdout),并且$return_value成功时包含0.

$output now contains whatever at printed to stderr (which should really go to stdout because it's not an error), and $return_value contains 0 on success.