在PHP exec中redirectSTDERR

我正在写一个PHP脚本,需要调用外部命令行工具,我正在使用exec()。 如果这一切都在本地正常工作,但是当我把它移动到一个活的服务器不再有效。

经过一些debugging,我认为问题归结于STDERRredirect – 如果我尝试做任何与redirect(redirect到STDIN,redirect到文件)的命令完全失败。

我写了一个简单的bat脚本来简化testing:

@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_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_get_contents()从流中读取数据。

我仍然不明白为什么有使用exec()的问题,但这种方法似乎在本地和服务器上工作 – 如果有人知道这是为什么,请让我知道!

$o = null; $r = null; exec("php test.php 2>&1", $o, $r ); 这很简单