Rocky Linux 8下PHP通过shell_exec调用bash脚本失败求助
问题排查:Rocky Linux 8下PHP通过网页执行/root目录bash脚本失败
环境信息
- PHP文件:
/var/www/mywebsite.com/index.php,权限apache:apache,权限值644 - Bash脚本:
/root/test.sh,权限root:root,权限值755 - PHP配置:
php.ini已将shell_exec从disable_functions中移除 test.sh内容:
#!/bin/bash echo 'hello';
已知测试结果
- root用户在控制台执行
/root/test.sh可正常运行 - PHP执行以下代码能正常输出日期:
$test = shell_exec('date'); echo $test;
- PHP执行以下代码均无输出(执行失败):
$test = shell_exec('/root/test.sh'); // 或 $test = shell_exec('sh /root/test.sh'); // 或 $test = shell_exec('/usr/bin/sh /root/test.sh'); echo $test;
排查与解决步骤
1. 核心问题:/root目录权限限制
Linux系统中/root目录默认权限是550,仅root用户和root组能进入。Apache运行用户是apache,这个用户根本没权限进入/root目录,哪怕脚本本身是755权限也没用——进入父目录是执行脚本的前提。
解决方法:
把脚本移到非root专属的目录,比如网站根目录下的scripts文件夹:
# 创建脚本目录 mkdir /var/www/mywebsite.com/scripts # 移动脚本 mv /root/test.sh /var/www/mywebsite.com/scripts/ # 确保apache有执行权限 chmod 755 /var/www/mywebsite.com/scripts/test.sh
然后PHP里的调用路径改成/var/www/mywebsite.com/scripts/test.sh
2. SELinux限制(Rocky Linux默认开启)
Rocky Linux 8默认开着SELinux,就算文件权限改对了,SELinux也可能拦着Apache执行脚本。
先检查SELinux状态:
getenforce
如果输出Enforcing,临时关闭测试:
setenforce 0
如果临时关闭后脚本能跑,说明是SELinux的问题,给脚本加安全上下文规则:
semanage fcontext -a -t httpd_sys_script_exec_t "/var/www/mywebsite.com/scripts/test.sh" restorecon -v "/var/www/mywebsite.com/scripts/test.sh"
这样SELinux就允许Apache执行这个脚本了。
3. 脚本语法修正
原test.sh把shebang和命令写在一行,正确写法应该分两行:
#!/bin/bash echo 'hello'
虽然root执行可能没问题,但这种写法可能导致执行异常,建议修正。
4. 捕获错误信息
shell_exec默认只返回标准输出,不返回错误信息,你可以加2>&1把错误输出转成标准输出,方便排查:
$test = shell_exec('/root/test.sh 2>&1'); echo $test;
如果是权限问题,会直接输出Permission denied这类错误,帮你快速定位。
内容的提问来源于stack exchange,提问作者lenawaii
相关产品推荐
相关产品推荐

