php exec:不返回输出

alb*_*anx 9 php windows iis exec

我有这个问题:在ISS Web服务器上,安装了Windows 7 x64专业版,zend服务器.在php下运行此命令:

exec('dir',$output, $err);
Run Code Online (Sandbox Code Playgroud)

$output is empty, $err=1.所以exec没有退回输出,似乎有一些错误.PHP disable_functions是空的,php不是安全模式,是标准的,我检查所有选项.这似乎是一般错误,即使在谷歌上搜索也不会给出结果.

请写下他的每一个经验和最终的解决方案或解决方法.

Tre*_*non 13

有几个帖子在PHP手册的相关部分,如这一个:

我在使用PHP exec命令执行任何批处理文件时遇到问题.执行其他命令(即"dir")工作正常.但是如果我执行了一个批处理文件,我收到了exec命令的输出.

我的服务器设置包括运行IIS6和PHP 5.2.3的Windows Server 2003服务器.在这台服务器上,我有:

  1. 授予对c:\ windows\system32\cmd.exe上的Internet用户的执行权限.
  2. 授予所有人 - >完全控制写入批处理文件的目录.
  3. 授予每个人 - >完全控制整个c:\ cygwin\bin目录及其内容.
  4. 授予Internet用户"以批处理方式登录"权限.
  5. 指定要执行的每个文件的完整路径.
  6. 测试了从服务器上的命令行运行的这些脚本,它们工作得很好.
  7. 确保%systemroot%\ system32位于系统路径中.

事实证明,即使在服务器上使用了上述所有内容,我也必须在exec调用中指定cmd.exe的完整路径.

当我使用电话时: $output = exec("c:\\windows\\system32\\cmd.exe /c $batchFileToRun");

一切都很好.在我的情况下,$batchFileToRun是批处理文件的实际系统路径(即调用realpath()的结果).

在手册页execshell_exec手册页上还有一些.或许通过它们可以得到它并为你工作.


Wes*_*tie 9

从命令中获得零输出的主要原因dir是因为dir不存在.它是命令提示符的一部分,在这个页面的某个地方,这个特定问题的解决方案很好.

你可以通过按WIN + R,输入dir或输入来找到这个start- 出现错误信息!

不管这听起来有多么反常,我发现在Windows中执行任何相关过程的最可靠方法是使用组件对象模型.你说让我们分享一下我们的经历吧?

$ me听到人们在笑

恢复了你的沉着吗?

所以,首先我们将创建COM对象:

$pCOM = new COM("WScript.Shell");
Run Code Online (Sandbox Code Playgroud)

然后,我们将运行需要运行的东西.

$pShell = $pCom->Exec("C:\Random Folder\Whatever.exe");
Run Code Online (Sandbox Code Playgroud)

凉!现在,这将一直挂起,直到一切都在二进制文件中完成.所以,我们现在需要做的就是抓住输出.

$sStdOut = $pShell->StdOut->ReadAll;    # Standard output
$sStdErr = $pShell->StdErr->ReadAll;    # Error
Run Code Online (Sandbox Code Playgroud)

您还可以执行其他一些操作 - 找出进程ID,错误代码等等.虽然此示例适用于Visual Basic,但它基于相同的方案.


Flo*_*ian 5

编辑:经过一些研究,我看到执行DIR命令的唯一方法是这样的:

cmd.exe /c dir c:\
Run Code Online (Sandbox Code Playgroud)

所以你可以尝试使用我的解决方案:

$command = 'cmd.exe /c dir c:\\';
Run Code Online (Sandbox Code Playgroud)

您也可以使用proc_open函数,这样您就可以访问stderr,返回状态代码和标准输出.

    $stdout = $stderr = $status = null;
    $descriptorspec = array(
       1 => array('pipe', 'w'),  // stdout is a pipe that the child will write to
       2 => array('pipe', 'w') // stderr is a pipe that the child will write to
    );

    $process = proc_open($command, $descriptorspec, $pipes);

    if (is_resource($process)) {
        // $pipes now looks like this:
        // 0 => writeable handle connected to child stdin
        // 1 => readable handle connected to child stdout
        // 2 => readable handle connected to child stderr

        $stdout = stream_get_contents($pipes[1]);
        fclose($pipes[1]);

        $stderr = stream_get_contents($pipes[2]);
        fclose($pipes[2]);

        // It is important that you close any pipes before calling
        // proc_close in order to avoid a deadlock
        $status = proc_close($process);
    }

    return array($status, $stdout, $stderr);
Run Code Online (Sandbox Code Playgroud)

与其他函数(如popen或exec)相比,proc_open的有趣部分是它提供了特定于Windows平台的选项,如:

suppress_errors (windows only): suppresses errors generated by this function when it's set to TRUE
bypass_shell (windows only): bypass cmd.exe shell when set to TRUE
Run Code Online (Sandbox Code Playgroud)