从 PHP 运行 at 不会给出任何输出


Running at from PHP gives no output

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

我要执行的命令是这样的:

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

echo exec("echo 'hi'");

这也输出了一些东西:

echo exec("atq");

但是,只要我使用at,就没有任何输出。如何获取以下输出:

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

因为目前当 PHP 通过 Apache 以"正常"方式运行时,它不会输出任何内容,但是在终端和 PHP 的交互式控制台中运行命令会给我预期的结果,如下所示:

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执行带有管道输入 echo 语句的at中获得任何输出时,exec()给我输出。我已经搜索并阅读了这个问题,但都无济于事。

如果使用带有 exec() 的第二个参数,我如何让exec()将输出从 at 返回到字符串或数组?

工作,单行解决方案

我没有意识到它可以这么简单。所需要的只是通过将 2>&1 stderr 放在要执行的命令末尾来将 stderr 重新路由到 stdout。现在,at的任何输出都打印到 stdout,因此由 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指出这一点,但是他删除了他的答案。引用:

据我所知,在输出到 stderr,这没有被捕获 执行官。我对此不太有信心,但请考虑使用 http://php.net/manual/en/function.proc-open.php,它允许您 将 STDERR 定向到自己的管道。

这其实才是正确的做事方式。我的解决方案(因为我只想要 stderr)是这样做:

// 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

这里有一个更复杂的proc_open解决方案。我写这个答案是因为,就我而言,"2>&1"解决方法不起作用。

function runCommand($bin, $command = '', $force = true)
{
    $stream = null;
    $bin .= $force ? ' 2>&1' : '';
    $descriptorSpec = array
    (
        0 => array('pipe', 'r'),
        1 => array('pipe', 'w')
    );
    $process = proc_open($bin, $descriptorSpec, $pipes);
    if (is_resource($process))
    {
        fwrite($pipes[0], $command);
        fclose($pipes[0]);
        $stream = stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        proc_close($process);
    }
    return $stream;
}

使用示例:

// getting the mime type of a supplied file
echo runCommand('file -bi ' . escapeshellarg($file));

另一个使用命令参数的示例:

// executing php code on the fly
echo runCommand('/usr/bin/php', '<?php echo "hello world!"; ?>');

另一个使用 force 参数的示例(这对于在执行过程中更改输出的命令很有用):

// converting an mp3 to a wav file
echo runCommand('lame --decode ' . escapeshellarg($source) . ' ' . escapeshellarg($dest), '', true);

我希望这有帮助:-)

尝试创建一个最小(非)工作示例。分解一切,一次只测试一件事。

这是你的抨击中的一个错误:

hpek@melda:~/temp$ echo 'php -f /path/to/file.php foo=1' | at now + 1 minutes
at: pluralization is wrong
job 22 at Sun Jun 10 14:48:00 2012
hpek@melda:~/temp$ 

minute而不是 og minutes .

我从at输出通过邮件发送给我!!