PHP脚本无法从Python脚本获取输出。

6
我在执行PHP脚本时遇到了一个问题,它无法执行Python脚本。我的客户使用Bluehost,因此我按照这里描述的easy_install方法安装了Python的第三方模块(numpy):https://my.bluehost.com/cgi/help/530?step=530 为了演示我的问题,我创建了两个Python脚本和一个PHP脚本。
hello.py 包含以下内容:
print "Hello, World!"

hello-numpy.py 包含以下内容:

import numpy
print "Hello, World!"

这个PHP脚本包含以下内容:

Output from exec('python hello.py'): <?php echo exec('python hello.py'); ?><br>
Output from exec('python hello-numpy.py'): <?php echo exec('python hello-numpy.py'); ?><br>
Output from exec('whoami'): <?php echo exec('whoami'); ?>

然后我从PHP获得以下输出:

exec('python hello.py')的输出:Hello, World!
exec('python hello-numpy.py')的输出:
exec('whoami')的输出:venicetw

然而,从SSH窗口运行这些脚本会产生以下结果:

# python hello.py
Hello, World!
# python hello-numpy.py
Hello, World!
# whoami
venicetw

似乎当Python脚本导入NumPy时,PHP没有任何输出,但是通过SSH可以正常工作。此外,对于hello.py,PHP得到了0的返回状态,但是对于hello-numpy.py,则得到了1。我认为这可能是权限问题,但是PHP和SSH都以"venicetw"用户运行。什么会阻止PHP和Apache从Python脚本中获取输出?这是我可以与Bluehost讨论的问题,还是其他我应该检查的问题?我们使用的是Apache 2.2.21PHP 5.2.17Python 2.4.3NumPy 1.6.0更新: SSH打印以下Python路径:
/home8/venicetw/public_html/venicenoise/python
/home8/venicetw/.local/lib/python2.4/site-packages/ogcserver-0.1.0-py2.4.egg
/home8/venicetw/.local/lib/python2.4/site-packages/PIL-1.1.7-py2.4-linux-x86_64.egg
/home8/venicetw/.local/lib/python2.4/site-packages/lxml-2.3.2-py2.4-linux-x86_64.egg
/home8/venicetw/.local/lib/python2.4/site-packages/WebOb-1.2b2-py2.4.egg
/home8/venicetw/.local/lib/python2.4/site-packages/PasteScript-1.7.5-py2.4.egg
/home8/venicetw/.local/lib/python2.4/site-packages/PasteDeploy-1.5.0-py2.4.egg
/home8/venicetw/.local/lib/python2.4/site-packages/Paste-1.7.5.1-py2.4.egg
/home8/venicetw/.local/lib/python2.4/site-packages/numpy-1.6.0-py2.4-linux-x86_64.egg
/home8/venicetw/.local/lib/python2.4/site-packages
/home8/venicetw/.local/lib/python/site-packages
/home8/venicetw/public_html/venicenoise/python
/usr/lib64/python24.zip
/usr/lib64/python2.4
/usr/lib64/python2.4/plat-linux2
/usr/lib64/python2.4/lib-tk
/usr/lib64/python2.4/lib-dynload
/usr/lib64/python2.4/site-packages
/usr/lib64/python2.4/site-packages/Numeric
/usr/lib64/python2.4/site-packages/PIL
/usr/lib64/python2.4/site-packages/gtk-2.0
/usr/lib/python2.4/site-packages

但是Apache只会打印这些Python路径:
/home8/venicetw/public_html/venicenoise/python
/usr/lib64/python24.zip
/usr/lib64/python2.4
/usr/lib64/python2.4/plat-linux2
/usr/lib64/python2.4/lib-tk
/usr/lib64/python2.4/lib-dynload
/usr/lib64/python2.4/site-packages
/usr/lib64/python2.4/site-packages/Numeric
/usr/lib64/python2.4/site-packages/PIL
/usr/lib64/python2.4/site-packages/gtk-2.0
/usr/lib/python2.4/site-packages

解决方法:通过在PHP和SSH中都执行 /usr/bin/env 命令,我确定了PHP缺少一个环境变量,这个变量是Python路径,其中numpy被安装。在这种情况下,只需添加以下代码:

putenv('PYTHONPATH=/home8/venicetw/.local/lib/python2.4/site-packages:/home8/venicetw/.local/lib/python/site-packages:');

将代码添加到PHP脚本的开头,一切都按预期运行。
1个回答

5
如果PHP返回状态为1,则表示您运行的进程遇到了错误。(在类Unix系统中,非零退出状态通常表示错误。但有一些程序是不同的,例如diff命令)。尝试检查子进程生成的stderr以查看打印的错误消息。
可以通过以下方式显示stderr:
Output from exec('python hello-numpy.py'):
    <?php echo exec('python hello-numpy.py 2>&1'); ?><br>
2>&1指令告诉Shell将stderrstdout合并成一个流。通常情况下,您不需要这样做,但这可以方便地查看错误。 更新:由于您收到的错误是ImportError: No module named numpy,我们可以尝试查看Python的路径。您的系统上可能安装了多个Python版本,并且Apache的环境(根目录等)可能与通过SSH运行Python时获得的环境不同。请在两个环境中执行此Python脚本:
import sys, os
for path in sys.path:
    print path
print
print 'Root:', os.readlink('/proc/self/root') # Linux only

其中一条路径应该指向安装numpy的位置,也许在您在Apache中运行时它不存在。或者可能Apache进程有不同的根目录,这将被Python进程继承。

解决方案: 缺少环境变量。请参考评论。


啊,出现了这个错误:“ImportError: No module named numpy”,我想知道是不是只需要重启Apache? - user1069895
确保两次访问的是相同的Python版本。 - Has QUIT--Anony-Mousse
如果有帮助的话,尝试使用虚拟环境,这样你就可以拥有相同的环境,将一个丢弃的环境作为问题。 - David Morabito
@Neil:重启Apache(可能)也不会有帮助。请参见编辑后的答案。 - Dietrich Epp
请看我的更新,这是结果。似乎Apache没有包含在.local中安装的模块。你的Linux-only行产生了错误“NameError: name 'os' is not defined”。 - user1069895
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接