PHP脚本无法从Python脚本输出

6 php python apache numpy

我在从PHP脚本执行Python脚本时遇到问题.我的客户端使用Bluehost,因此我使用此处描述的easy_install方法为Python安装了第三方模块(numpy):https://my.bluehost.com/cgi/help/530?step = 530

为了演示我的问题,我创建了两个python脚本和一个PHP脚本.

hello.py包含:

print "Hello, World!"
Run Code Online (Sandbox Code Playgroud)

hello-numpy.py包含:

import numpy
print "Hello, World!"
Run Code Online (Sandbox Code Playgroud)

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'); ?>
Run Code Online (Sandbox Code Playgroud)

然后我从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
Run Code Online (Sandbox Code Playgroud)

当Python脚本导入numpy时,似乎PHP没有得到任何输出,但它可以在SSH中正常工作.此外,PHP为hello.py返回0,但为hello-numpy.py返回1.我认为这可能是一个权限问题,但PHP和SSH都作为"venicetw"用户运行.什么会阻止PHP和Apache从Python脚本获取输出?这是我可以与Bluehost讨论的东西,还是我应该检查的其他东西?我们使用Apache 2.2.21,PHP 5.2.17,Python 2.4.3,和numpy 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
Run Code Online (Sandbox Code Playgroud)

但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
Run Code Online (Sandbox Code Playgroud)

解决方案:通过从PHP和SSH执行/ usr/bin/env,我能够确定PHP缺少安装numpy的Python路径的环境变量.在这种情况下,通过添加

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

到PHP脚本的开头,一切都按预期工作.

Die*_*Epp 5

如果PHP的返回状态为1,则表示您运行的进程遇到错误.(非零退出状态通常表示Unix样式系统上的错误.例如,几个程序是不同的diff.)尝试检查stderr子进程生成的内容以查看在那里打印的错误消息.

你可以这样展示stderr:

Output from exec('python hello-numpy.py'):
    <?php echo exec('python hello-numpy.py 2>&1'); ?><br>
Run Code Online (Sandbox Code Playgroud)

2>&1指示外壳相结合stderr,并stdout为一个流.您通常不希望这样做,但它可以很容易地看到错误.

更新:因为你得到的错误是ImportError: No module named numpy我们可以尝试查看Python的路径.您的系统上可能安装了多个Pythons,并且Apache的环境(根目录等)也可能与您通过SSH运行Python时获得的环境不同.尝试在两种环境中执行此Python脚本:

import sys, os
for path in sys.path:
    print path
print
print 'Root:', os.readlink('/proc/self/root') # Linux only
Run Code Online (Sandbox Code Playgroud)

其中一条路径应该指向numpy安装的位置,并且在Apache中运行时可能会丢失它.或者Apache进程可能有一个不同的根目录,它将由Python进程继承.

解决方案:缺少环境变量.看评论.