根本原因是php进程的$path环境变量与终端不一致,web服务器用户环境极简;需用绝对路径调用python解释器,确保工作目录正确,并避免路径拼接和跨平台问题。

PHP exec() 调用 Python 脚本时提示 No such file or directory
根本原因不是“路径写错了”,而是 PHP 进程的 $PATH 环境变量和你终端里看到的不一致——尤其是用 Web 服务器(如 Nginx + PHP-FPM)运行时,www-data 或 nginx 用户的环境极简,通常不含 /usr/local/bin 或用户自定义的 ~/bin。
- 别依赖
which python3的输出直接拼命令,Web 进程根本看不到你的 shell 配置 - 用绝对路径调用解释器:
exec('/usr/bin/python3 /var/www/scripts/test.py', $output, $return) - 检查 Python 脚本第一行是否含
#!/usr/bin/env python3——这在 PHPexec()下无效,因为env本身也要在$PATH里,而它往往不在 - 临时调试可加
env查看真实环境:exec('env | grep PATH', $env_out),对比你终端执行echo $PATH的结果
Python 脚本内部读取文件失败:相对路径在 PHP 下失效
PHP 执行 Python 时,工作目录(cwd)默认是 PHP 脚本所在目录,不是 Python 脚本所在目录。所以 open('data.txt') 会去 PHP 脚本目录下找,而非 test.py 目录。
- 在 Python 脚本开头加
import os; os.chdir(os.path.dirname(__file__))强制切到自身目录 - 或改用绝对路径构造:
os.path.join(os.path.dirname(__file__), 'data.txt') - 避免用
__file__做路径拼接后直接传给 PHP ——PHP 不解析 Python 的路径逻辑,只当字符串处理 - 如果 Python 脚本被 symlink 引用,
__file__返回的是链接路径,要用os.path.realpath(__file__)解析真实路径
跨平台路径硬编码导致 Linux 下报错:Windows 风格路径混入
常见于从 Windows 开发环境直接复制代码:路径中含 C:\scripts\foo.py 或用 \ 分隔,Linux 下 exec() 会把反斜杠当转义符,最终传给系统的是损坏路径。
- 所有路径字符串必须用正斜杠
/,且以/开头表示绝对路径(如/var/www/app/script.py) - 禁用字符串拼接路径:
'/var/www/' + script_name容易漏掉/;改用dirname . '/' . basename或 PHP 的realpath()+dirname() - 若脚本名来自用户输入,务必用
basename()过滤,防止路径穿越(如../../etc/passwd) - Python 侧也需防御:用
os.path.abspath()和os.path.commonpath()校验路径是否落在允许目录内
PHP-FPM 下无法访问虚拟环境 Python 可执行文件
你激活了 venv 后在终端能跑通,但 PHP 里 exec('/path/to/venv/bin/python script.py') 仍失败,大概率是权限或动态库问题。
立即学习“PHP免费学习笔记(深入)”;
- 确认
/path/to/venv/bin/python对 PHP 进程用户(如www-data)有x权限:chmod +x /path/to/venv/bin/python - venv 的
python是硬链接或软链接?PHPexec()对软链接支持稳定,但某些精简系统(如 Alpine)可能缺libc,导致ldd /path/to/venv/bin/python报not found - 更稳妥的方式是用系统 Python +
-m venv模式加载包:/usr/bin/python3 -m pip install --target /path/to/venv/lib/python3.x/site-packages/ ...,再统一走系统解释器 - 避免在 venv 的
bin/下放带空格或特殊字符的路径,PHPexec()对 shell 字符转义很脆弱
最常被忽略的一点:PHP 的 exec()、shell_exec() 默认不继承父进程的环境变量,哪怕你在 php.ini 里设了 variables_order = "EGPCS" 也没用。路径问题本质是环境隔离问题,不是语法问题。











