在PHP exec中重定向STDERR

在PHP exec中重定向STDERR,php,windows,exec,wamp,windows-server-2008,Php,Windows,Exec,Wamp,Windows Server 2008,我正在编写一个PHP脚本,需要对外部命令行实用程序进行一些调用,我正在使用exec()进行调用。它在本地运行得很好,但当我将它转移到一个实时服务器时,它就不再工作了 经过一些调试后,我认为问题在于STDERR重定向-如果我尝试任何与重定向有关的操作(重定向到STDIN,重定向到文件),那么命令将完全失败 我编写了一个简单的bat脚本来简化测试: @echo off echo STDOUT test echo STDERR test 1>&2 然后在PHP中: <?php $

我正在编写一个PHP脚本,需要对外部命令行实用程序进行一些调用,我正在使用exec()进行调用。它在本地运行得很好,但当我将它转移到一个实时服务器时,它就不再工作了

经过一些调试后,我认为问题在于STDERR重定向-如果我尝试任何与重定向有关的操作(重定向到STDIN,重定向到文件),那么命令将完全失败

我编写了一个简单的bat脚本来简化测试:

@echo off
echo STDOUT test
echo STDERR test 1>&2
然后在PHP中:

<?php
$cmd = "_test.bat 2>&1";
exec($cmd, $output, $status);
var_dump($output);
var_dump($status);
?>

在本地服务器上,结果是$status=0、$output=array(“STDOUT test”、“STDERR test”),正如我所期望的那样,但在实时服务器上,结果是$status=1,而输出是一个空数组

如果删除1>&2部分,则两个部分的结果都相同(只是STDOUT部分),因此命令本身显然是按预期工作的


这里有没有我遗漏的简单的东西?如果有帮助,服务器将运行Windows server 2008 R2。

为任何遇到类似问题的人提供更新和回答

在这方面花了很多时间之后,我放弃了
exec()
,而是尝试了
proc\u open()

这样做现在可以在本地和服务器上工作:

<?php
$cmd = "__test.bat";

$descriptorspec = array(
    0 => array("pipe", "r"), // STDIN
    1 => array("pipe", "w"), // STDOUT
    2 => array("pipe", "w"), // STDERR
);
$cwd = getcwd();
$env = null;

$proc = proc_open($cmd, $descriptorspec, $pipes, $cwd, $env);
if (is_resource($proc)) {
    // Output test:
    echo "STDOUT:<br />";
    echo "<pre>".stream_get_contents($pipes[1])."</pre>";
    echo "STDERR:<br />";
    echo "<pre>".stream_get_contents($pipes[2])."</pre>";
    $return_value = proc_close($proc);
    echo "Exited with status: {$return_value}";
}
?>

出于某种原因,缺少
getcwd()
部分会导致命令在服务器上失败,除非我指定完整的路径,而在本地这不是问题

使用此方法,我可以附加
2>&1
,将所有输出重定向到STDIN。要输出到文件,手册显示$descriptorspec数组可以修改,例如:
2=>array(“file”、“stderr.log”、“a”)
(不过我还没有测试过这个)

这里的一个区别是,如果我想用PHP检索输出,而不是获取数组中的所有行,我需要使用
stream\u get\u contents()
从流中读取

我仍然不明白为什么在使用
exec()
时会出现问题,但这种方法似乎在本地和服务器上都有效-如果有人知道为什么会出现这种情况,请告诉我

$o=null;
$r=null;
exec(“php test.php 2>&1”,$o,$r);

这很简单

也许你应该尝试使用
\u test.bat的绝对路径
。感谢你的评论,只是尝试使用完整路径,我仍然得到相同的结果-只要我不尝试用2>&1重定向STDERR,该命令就可以工作。问题是,我需要捕获STDERR!检查
php.ini
中的
display\u errors
指令-它应该设置为
stderr
它被设置为1,我已将它更改为stderr,但它仍在执行相同的操作您重新启动了Web服务器吗?如果不是,我想你需要。我还有一个建议。您可以尝试使用php的处理程序()。是的,这也适用于Windows,2>文件名也是如此