使用php读取python程序的实时输出

时间:2016-02-09 13:41:49

标签: php python linux real-time

我正在制作一个执行python程序的PHP网页,当python程序运行时,它会实时显示输出。 在关注this answer之后,这是我正在尝试的代码。

$cmd = 'python execs/reduction_code.py';
while(@ ob_end_flush());

$proc = popen($cmd, 'r');
echo '<pre class="box">';

while(!feof($proc)){
    echo fread($proc, 4096);
    @ flush();
}

echo '</pre>';
pclose($proc);

在我开始执行程序reduction_code.py之后,每30秒显示一些打印语句(告诉程序的状态)。该程序大约需要25分钟才能完全执行。当我使用终端运行python程序时,这很有效。

然而,当我使用上面的PHP代码运行它时,它根本不显示任何输出。文件reduction_code.py是可执行文件,apache具有执行和读取它的权限。

此外,当我通过将$cmd中的值替换为$cmd = 'python execs/test.py';来运行一个简单的python程序来ping地址时,我在页面中获得了预期的ping探测实时输出。

test.py是:

from subprocess import call
call(["ping", "-c", "10", "localhost"])

我是PHP的新手,我不知道为什么在运行reduction.py后,页面根本没有输出。

编辑1 :当我使用$proc = popen($cmd.' 2>&1', 'r');代替$proc = popen($cmd, 'r');来访问shell返回的任何错误消息时。我在我的网页上打印了此错误消息(预计会出现输出的位置)。

Resource id #9/usr/lib/python2.7/site-packages/IPython/utils/path.py:296: UserWarning: IPython parent '/root' is not a writable location, using a temp directory." using a temp directory."%parent)

/usr/lib64/python2.7/site-packages/astropy/config/configuration.py:687: ConfigurationMissingWarning: Configuration defaults will be used due to OSError:13 on None warn(ConfigurationMissingWarning(msg))
Traceback (most recent call last):
  File "execs/reduction_code.py", line 8, in 
    import matplotlib.pyplot as plt
  File "/usr/lib64/python2.7/site-packages/matplotlib/pyplot.py", line 26, in 
    from matplotlib.figure import Figure, figaspect
  File "/usr/lib64/python2.7/site-packages/matplotlib/figure.py", line 24, in 
    import matplotlib.artist as martist
  File "/usr/lib64/python2.7/site-packages/matplotlib/artist.py", line 7, in 
    from transforms import Bbox, IdentityTransform, TransformedBbox, \
  File "/usr/lib64/python2.7/site-packages/matplotlib/transforms.py", line 35, in 
    from matplotlib._path import (affine_transform, count_bboxes_overlapping_bbox,
ImportError: /opt/lampp/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by /usr/lib64/python2.7/site-packages/matplotlib/_path.so)

2 个答案:

答案 0 :(得分:1)

听起来你需要使Python的输出无缓冲 - 默认情况下,从命令行运行时会打开,但否则会关闭。解决这个问题的最简单方法是在脚本开头的hashbang中添加-u参数:

#!/usr/bin/python -u

答案 1 :(得分:0)

我找到了回答我的问题。在输出的最后一行报告错误:

ImportError: /opt/lampp/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by /usr/lib64/python2.7/site-packages/matplotlib/_path.so)

我发现here Lampp正在使用的库太旧而且没有定义GLIBCXX_3.4.9。所以,首先我将/opt/lampp/lib/libstdc++.so.6重命名为/opt/lampp/lib/libstdc++.so.6.orig,然后通过更改命令来更改LD_LIBRARY_PATH:

$proc = popen($cmd.' 2>&1', 'r');

到此:

$proc = popen("LD_LIBRARY_PATH=/usr/lib/ ".$cmd.' 2>&1', 'r');

在我改变之后运行我的程序后,生成了另一个报告

的报告
Runtime Error: could not open display

在进行了一些搜索后,我发现hereherematplotlib库的问题。我了解到matplotlib库默认使用X-using后端。并且使用X-back后端的服务器很少。所以我按照答案将这两行插入我的reduction_code.py程序

import matplotlib
matplotlib.use('Agg')

现在,一切都按预期工作。感谢您的支持。