php exec:不返回outpu

2024-05-15 10:02:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这个问题: 在ISS web服务器上,安装了windows 7 x64 professional zend服务器。在php下运行此命令:

exec('dir',$output, $err);

$output is empty, $err=1.因此exec没有返回输出,它似乎有一些错误。 Phpdisable_functions为空,Php未处于安全模式,为标准,我选中所有选项。 这似乎是一个普遍的错误,即使在谷歌上搜索也不会给出结果。

请写下每个人的经验和最终的解决方案或解决办法。


Tags: 命令服务器weboutputiswindows错误dir
3条回答

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

cmd.exe /c dir c:\

因此您可以使用以下方法尝试我的解决方案:

$command = 'cmd.exe /c dir c:\\';

您也可以使用proc_open函数,该函数允许您访问stderr、返回状态码和stdout。

    $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);

与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

在PHP手册的相关章节中有一些文章,比如this one

I was having trouble using the PHP exec command to execute any batch file. Executing other commands (i.e., "dir") works fine). But if I executed a batch file, I receieved no output from the exec command.

The server setup I have consists of Windows Server 2003 server running IIS6 and PHP 5.2.3. On this server, I have:

  1. Granted execute permissions to the Internet User on c:\windows\system32\cmd.exe.
  2. Granted Everyone->Full Control to the directory in which the batch file is written.
  3. Granted Everyone->Full Control on the entire c:\cygwin\bin directory and its contents.
  4. Granted the Internet User "log on as batch" permissions.
  5. Specified the full path to each file being executed.
  6. Tested these scripts running from the command line on the server and they work just fine.
  7. Ensured that %systemroot%\system32 is in the system path.

It turns out that even with all of the above in place on the server, I had to specify the full path to cmd.exe in the exec call.

When I used the call: $output = exec("c:\\windows\\system32\\cmd.exe/c $batchFileToRun");

then everything worked fine. In my situation, $batchFileToRun was the actual system path to the batch file (i.e., the result of a call to realpath()).

^{}^{}手册页上还有更多内容。也许跟随他们会让你振作起来为你工作。

从命令(如dir)获得零输出的主要原因是dir不存在。这是命令提示符的一部分,解决这个问题的方法很好,就在这个页面的某个地方。

您可以通过按WIN + R,然后键入dirstart来找到这一点-出现错误消息!

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

我听到人们在笑

恢复平静了吗?

因此,首先我们将创建COM对象:

$pCOM = new COM("WScript.Shell");

然后,我们只运行任何需要运行的程序。

$pShell = $pCom->Exec("C:\Random Folder\Whatever.exe");

太酷了!现在,它将一直挂起,直到二进制文件中的所有内容都完成。所以,我们现在需要做的是获取输出。

$sStdOut = $pShell->StdOut->ReadAll;    # Standard output
$sStdErr = $pShell->StdErr->ReadAll;    # Error

您还可以做一些其他的事情-找出进程ID、错误代码等。虽然this example是针对Visual Basic的,但它基于相同的方案。

相关问题 更多 >