PHP调用exec执行Python脚本被拒的主因是Web服务器进程权限不足,需检查绝对路径、目录x权限、disable_functions限制及SELinux/AppArmor策略。

PHP调用exec()执行Python脚本被拒绝:先看错误来源
不是PHP没权限,而是Web服务器(如Apache或Nginx)启动的PHP进程,以低权限用户(如www-data或nginx)运行,无法直接访问你个人用户目录下的Python文件,或没有执行权。典型错误是:Permission denied或Operation not permitted。
检查Python脚本路径与所有权
Web进程看不到/home/yourname/script.py,除非路径全局可读,且所有中间目录都有x(执行)权限(Linux下目录的x位决定能否cd进入)。
-
ls -ld /home/yourname→ 若显示drw-------,则需改为chmod 755 /home/yourname -
ls -l /var/www/html/script.py→ 推荐把脚本移到Web根目录下(如/var/www/html/tools/),避免家目录权限干扰 - 确保脚本本身可读可执行:
chmod 755 script.py;若用python3 script.py调用,脚本无需+x,但目录仍需x
PHP中调用方式与安全限制
别用exec("python3 ~/script.py")——~在Web进程里不展开,且exec默认被禁用或受open_basedir、disable_functions限制。
- 确认
exec未被禁用:echo ini_get('disable_functions');→ 若含exec,需改php.ini并重启PHP服务 - 用绝对路径调用:
exec('/usr/bin/python3 /var/www/html/tools/script.py 2>&1', $output, $return_code) - 加
2>&1捕获错误输出,$return_code非0时查$output具体内容,比盲目改权限更有效 - 避免使用
shell_exec或拼接用户输入,防止命令注入
SELinux或AppArmor导致的静默拦截
CentOS/RHEL启用了SELinux,Ubuntu可能启用了AppArmor,它们会阻止Apache/Nginx执行外部二进制,即使文件权限全开。
立即学习“PHP免费学习笔记(深入)”;
- 临时测试是否是它:运行
setenforce 0(SELinux)或aa-disable /usr/sbin/apache2(AppArmor),再试PHP调用;若成功,说明是策略问题 - 永久修复不要关SELinux,而是用
audit2why -a查拒绝日志,再用audit2allow生成策略模块 - 常见策略补丁:
setsebool -P httpd_can_network_connect 1(允许网络)、httpd_can_execmem 1(若Python用到某些C扩展)
$output和$return_code → 确认路径是否绝对且可遍历 → 检查disable_functions → 最后排查SELinux/AppArmor。很多“改了777还是不行”的情况,卡在目录缺少x位或SELinux上。











