Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PHP获取实时结果shell_Php_Batch File - Fatal编程技术网

使用PHP获取实时结果shell

使用PHP获取实时结果shell,php,batch-file,Php,Batch File,我必须执行一个批处理文件(即bat),并在HTML页面上获得结果 我使用以下PHP代码得到一个结果: <?php echo "<br>"; $result = shell_exec('start file.bat'); iconv("CP850","UTF-8",$result); echo "<pre>$result </pre>"; ?> 现在的问题是,我只在批处理文件执行完成时才得到结果,我希望实时得到结

我必须执行一个批处理文件(即bat),并在HTML页面上获得结果

我使用以下PHP代码得到一个结果:

<?php
    echo "<br>";
    $result = shell_exec('start file.bat');
    iconv("CP850","UTF-8",$result);
    echo "<pre>$result </pre>";
?>


现在的问题是,我只在批处理文件执行完成时才得到结果,我希望实时得到结果,就像通过命令行运行一样。

可以在PHP的shell_exec文档页面的注释中找到

如果您试图在shell_exec中运行“gunzip-t”之类的命令并得到一个空结果,则可能需要在命令末尾添加2>&1,例如:

不总是有效的: echo shell_exec(“gunzip-c-t$path_to_backup_file”)

应: echo shell_exec(“gunzip-c-t$path_to_backup_file 2>&1”)

在上面的示例中,gunzip输出开头的换行符似乎阻止了shell_exec打印任何其他内容。希望这能为其他人节省一两个小时

我相信这是你真正需要做的


参考:

正如您的问题评论中已经提到的,您需要以您可以与之沟通的方式完成一个过程。这在像
exec()
之类的简单函数中是不可能的

请看一个简单的例子:

文件
test.sh

<?php
$descriptorspec = array(
   0 => array('pipe', 'r'),
   1 => array('pipe', 'w'),
);

echo "forking process ...\n";
$process = proc_open('./test.sh', $descriptorspec, $pipes);

if (is_resource($process)) {
    echo "... successfully forked process ...\n";

    while (!feof($pipes[1])) {
        echo fread($pipes[1], 1024);
        flush();
    }

    echo "... process has finished ...\n";
    fclose($pipes[0]);
    fclose($pipes[1]);
    echo "... pipes closed ...\n";

    proc_close($process);
    echo "... process closed.\n";
} else {
    echo "... failed to fork process!\n";
}
文件
test.php

forking process ...
... successfully forked process ...
start counting ...
* counter is at value 1 *
* counter is at value 2 *
* counter is at value 3 *
... finished counting.
... process has finished ...
... pipes closed ...
... process closed.
但有趣的是,这个输出不是在分叉过程完成后一次性发送的,而是您所说的“实时方式”。因此,前四行立即出现,接下来的两行各有3秒的延迟,然后是其余的输出


请注意,上面的示例旨在演示Linux CLI环境。因此,它不关心html标记,而是输出纯文本,并依赖
bash
作为分叉进程的shell环境。显然,您必须根据自己的需要调整简单的演示

您是否考虑过将命令从.bat文件移到PHP代码中?这将允许您回显每个命令的结果。@DanielSamson同样,只有当cmd finish exect您需要使用基于套接字的方法来分叉进程,而不是依赖原始函数,如
exec()
或类似函数时,才会产生结果。这意味着您分叉了一个进程,但通过套接字与该进程通信。它允许转发进程立即创建的任何输出。但它要复杂得多。事实上,我不确定在微软的Windows平台上是否也能做到这一点。我只在普通的Linux系统上做过几次。
forking process ...
... successfully forked process ...
start counting ...
* counter is at value 1 *
* counter is at value 2 *
* counter is at value 3 *
... finished counting.
... process has finished ...
... pipes closed ...
... process closed.