PHP 7使用shell_exec/exec调用Python脚本返回NULL问题求助
你遇到的这个情况我之前也碰到过,shell_exec返回NULL通常有两种核心可能:要么脚本根本没启动执行,要么执行过程中出错但错误信息没被捕获到——毕竟shell_exec默认只返回标准输出,标准错误会直接被丢弃。结合你已经排查的权限、safe_mode等情况,给你几个针对性的排查方向:
1. 先捕获错误输出,拿到关键线索
这是最优先要做的!把Python脚本的标准错误(stderr)重定向到标准输出(stdout),这样shell_exec就能返回错误信息了,修改后的代码如下:
var_dump(shell_exec("/usr/bin/python3 /home/pi/Documents/GTranslate/translator.py 2>&1"));
执行后你就能看到具体的错误细节——比如依赖库找不到、语法错误、脚本读写的其他文件权限不足等,这一步能帮你直接定位问题根源。
2. 检查PHP运行用户的环境依赖
PHP通常是以www-data用户运行的(Apache或php-fpm的默认用户),而你在pi用户下能正常运行脚本,不代表www-data也具备相同的环境:
- 脚本用到的第三方Python库(比如googletrans、requests等)可能只在pi用户的环境下安装了,www-data用户没有权限访问。你可以尝试用www-data身份直接执行脚本测试:
如果报错说找不到模块,就给www-data安装对应的依赖,比如:sudo -u www-data /usr/bin/python3 /home/pi/Documents/GTranslate/translator.pysudo -u www-data pip3 install googletrans==4.0.0-rc1 - 另外,Python的环境变量路径也可能存在差异,你可以在脚本开头添加
print(sys.path)输出路径,对比pi用户和www-data用户的环境差异。
3. 排查脚本的工作目录问题
如果你的Python脚本里用到了相对路径(比如读取同目录下的配置文件、资源文件),PHP运行时的工作目录可能不是脚本所在的目录,导致脚本找不到依赖文件。可以先切换到脚本目录再执行:
var_dump(shell_exec("cd /home/pi/Documents/GTranslate && /usr/bin/python3 translator.py 2>&1"));
4. 验证脚本的shebang(直接执行脚本路径时)
如果你尝试直接运行/home/pi/Documents/GTranslate/translator.py,要确保脚本第一行的shebang是正确的:
#!/usr/bin/python3
虽然你已经设置了可执行权限,但shebang错误会导致系统找不到正确的解释器,同样会返回NULL。
5. 检查系统安全限制(AppArmor)
Debian 9默认可能启用了AppArmor,它会限制Apache/php-fpm进程的执行范围。你可以检查AppArmor的状态:
sudo aa-status
如果看到apache2的profile处于enforcing状态,可能需要修改配置允许访问你的脚本路径,或者临时切换为complain模式测试(不建议长期关闭):
sudo aa-complain /etc/apparmor.d/usr.sbin.apache2
先从第一步开始,拿到错误信息后就能精准解决问题了!
内容的提问来源于stack exchange,提问作者Timmy

