tom*_*990 5 php windows wamp exec windows-server-2008
我正在编写一个需要调用外部命令行实用程序的 PHP 脚本,我正在使用 exec() 进行调用。在本地一切正常,但是当我将其移至实时服务器时,它不再起作用。
经过一些调试,我相信问题归结为 STDERR 重定向 - 如果我尝试与重定向有关的任何事情(重定向到 STDIN,重定向到文件),则命令完全失败。
我写了一个简单的bat脚本来简化测试:
@echo off
echo STDOUT test
echo STDERR test 1>&2
Run Code Online (Sandbox Code Playgroud)
然后在 PHP 中:
<?php
$cmd = "_test.bat 2>&1";
exec($cmd, $output, $status);
var_dump($output);
var_dump($status);
?>
Run Code Online (Sandbox Code Playgroud)
在本地服务器上,结果是 $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}";
}
?>
Run Code Online (Sandbox Code Playgroud)
由于某种原因,丢失该getcwd()部分会导致命令在服务器上失败,除非我指定完整路径,而在本地这不是问题。
使用此方法,我可以附加2>&1将所有输出重定向到 STDIN。要输出到文件,手册显示可以修改 $descriptorspec 数组,例如:(2 => array("file", "stderr.log", "a")不过我还没有测试过)
这里的一个区别是,如果我想检索 PHP 中的输出,而不是获取数组中的所有行,我需要使用stream_get_contents().
我仍然不明白为什么使用存在问题exec(),但这种方法似乎在本地和服务器上都有效 - 如果有人知道为什么会这样,请告诉我!
| 归档时间: |
|
| 查看次数: |
4442 次 |
| 最近记录: |