You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP 7.0 exec执行shell脚本时www-data无法写入/创建文件问题

PHP 7.0 exec执行shell脚本失败的排查与解决

我之前也碰到过一模一样的问题——命令行用www-data跑脚本完全正常,一放到PHP的exec里就罢工,大概率是环境、权限或者安全限制在搞鬼,给你梳理几个实用的排查方向和解决办法:

1. 环境变量差异是重灾区

命令行下的www-data和PHP-FPM/mod_php运行的www-data,环境变量完全不是一回事!比如PATH,脚本里如果用了cp、rsync这类命令,PHP可能根本找不到它们的安装路径。

解决办法:

  • 把脚本里的所有命令都改成绝对路径,比如用/usr/bin/cp代替cp,/usr/bin/rsync代替rsync(可以在命令行用which cp查具体路径)。
  • 或者在exec调用里手动指定环境变量,比如:
    exec('export PATH=/usr/bin:/bin:/usr/sbin:/sbin && sh /var/www/sync.sh 2>&1', $output, $return_var);
    

2. 捕获错误输出才能找到根源

PHP的exec默认只抓取标准输出(stdout),脚本执行的错误信息(stderr)会直接被丢掉,你根本不知道到底哪里出问题了!

解决办法:
修改你的exec调用,把错误输出重定向到标准输出,同时捕获返回码和执行日志:

$output = [];
$return_code = 0;
exec('sh /var/www/sync.sh 2>&1', $output, $return_code);

echo "脚本返回码: " . $return_code . "\n";
echo "执行输出:\n";
print_r($output);

返回码非0就说明脚本执行失败,输出内容会明确告诉你是权限不够、命令找不到还是路径写错了。

3. 脚本和路径的权限/路径坑

  • 先确认/var/www/sync.sh的权限:至少要给www-data执行权限,比如设置chmod 755 /var/www/sync.sh,同时确保www-data能读取这个文件。
  • 脚本里的相对路径要人命!比如脚本里写./data.log,命令行跑的时候工作目录是/tmp/data,但PHP执行时的工作目录可能是/var/www或者服务器根目录,所以一定要改成绝对路径/tmp/data/data.log。

4. PHP的安全配置限制

检查PHP的配置文件(php.ini):

  • 看看disable_functions里有没有exec,如果有就把它删掉,然后重启PHP服务。
  • 看看open_basedir设置,如果它限制了PHP能访问的目录,要确保/tmp和/var/www都在允许列表里,比如open_basedir = /var/www/:/tmp/。

5. SELinux或AppArmor的拦截

如果你的服务器开了SELinux(常见于CentOS/RHEL)或者AppArmor(常见于Ubuntu),它们可能会阻止PHP执行外部脚本或者访问/tmp目录。

排查办法:

  • SELinux:执行getenforce,如果显示Enforcing,临时关闭试试setenforce 0,再测试脚本。如果能正常运行了,就需要添加SELinux规则允许PHP访问相关资源。
  • AppArmor:执行aa-status看看有没有针对PHP的配置,临时禁用systemctl stop apparmor测试,没问题的话再调整规则。

内容的提问来源于stack exchange,提问作者user3592217

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:25:13