记一次php exec函数执行shell脚本的过程

1、开启exec函数,出于安全考虑,默认是没有开启exec函数的,没有开启之前,直接运行exec函数,会有下面的提示:

Warning: exec() has been disabled for security reasons in /home/wwwroot/baidu/test.php

开启方法:我用的是宝塔面板,点击“软件商店”,找到对应的php版本(我用的是PHP-7.2),点击“设置”“配置文件”,找到disable_functions里的exec函数,将其去掉即可;或者直接在配置文件“/home/server/php/72/etc/php.ini”修改也行

宝塔面板禁用exec函数

开启后,正常自己网站目录里面的shell脚本都可以正常运行,如下:

<?php
 exec("/home/wwwroot/baidu/test.sh", $result); 
 var_dump($result); 
?>
array(1) {
   [0]=>
   string(11) "hello world!"
 }

但是后面遇到的新问题是要执行的脚本并没有在网站的根目录下,而是在其他非webroot目录,我的文件在新建用户user0对应目录/home/user0下,执行命令exec(“/home/user0/test.sh”, $result); 怎么都没有输出,百度了很多文档也没有找到合适的解决方法,这个问题直接困扰了我几天

2、解决方法一,让php利用root权限去执行shell脚本

<?php
exec("whoami",$result);// 查看当前网站属于哪个用户 
var_dump($result);// 查看到用户名是www
?>
array(1) {
   [0]=>
   string(3) "www"
 }
vi /etc/sudoers // 修改sudoers文件,为www用户赋予root权限,并且不需要密码,添加下面内容,保存后实时生效
www  ALL=(root)  NOPASSWD:ALL //执行shell时,第一个www是用户名,第一个ALL是指所有主机,(root)表示要使用哪个用户的权限,NOPASSWD表示不需要密码,最后一个ALL表示可以使用root用户的所有命令,如果只使用部分命令,这个地方可以改成具体的某几个命令 

配置好后,在要执行的命令前加上sudo,即可正常获得输出结果

<?php
 exec("sudo /home/user0/test.sh", $result); 
 var_dump($result); 
?>
array(1) {
   [0]=>
   string(11) "hello world!"
 }

这样是解决了遇到的问题,但是www用户突然权限太高,安全方面又是个问题了,为了解决安全问题,推荐下面的解决方法

3、方法二,更改要执行文件的用户组和www用户在同一个用户组,并设置对应组权限即可执行非web目录脚本【推荐】

通过运行下面的函数,发现www用户是没法读取和运行测试脚本的

<?php
$scriptPath = '/home/user0/test.sh';
var_dump(array(
     'file' => is_file($scriptPath),
     'readable' => is_readable($scriptPath),
     'executable' => is_executable($scriptPath)
));
array(3) {
   ["file"]=>
   bool(false)
   ["readable"]=>
   bool(false)
   ["executable"]=>
   bool(false)
 }
?>

执行下面2条命令后,www用户就可以访问和执行user0目录下的文件了;也不用配置/etc/sudoers这个文件;命令的含义是即把www用户附加到user0用户组,并设置user0目录下的文件和文件夹对应的用户组具有读取和执行权限,如果权限没有设置,则会提示permission denied

usermod -a -G user0 www //将www用户附加到user0用户组
chmod -R 750 /home/user0 //设置user0用户组权限可读和可执行

注意:要访问或者执行test.sh,test.sh上级所有层的目录都必须同时满足有被访问或执行的权限,执行test.sh才会生效,之前调试一直不成功是这个原因导致的

设置好后,即可正常执行非web目录外的脚本了

<?php
exec("/home/user0/test.sh", $result); 
var_dump($result);
?> 
array(1) {
   [0]=>
   string(11) "hello world"
}

4、学到的一些Linux相关命令,总结整理如下

ls -l /home/user0/ #查看文件或者文件夹所属用户和用户组

groupadd user0 #新建用户组user0 
groups user1 #查看用户user0属于哪个用户组
groupdel  user0 #删除用户组user0 
——————————————————————————————————————
useradd -g user0 user1  #新建用户user1并将其添加到用户组user0  -g 分到哪个组 
useradd -d /home/user0 -g user0 user1  #新建用户user1并将其添加到用户组user0  -d宿主目录  -g 分到哪个组

passwd user1 #为用户设置初始密码
—————————————————————————————————————— 
userdel user1 # 删除用户
userdel -r user1 # 连同用户所属的目录一起删除

php如何让某个用户访问其他用户目录,将用户归为1个组(group)并设置好权限即可

chown:修改文件或者文件夹所属组
chown -R UserName:GroupName /home/user0/ # -R是目录下所有文件 用户名:用户组 

usermod:将一个已有用户添加到一个已有用户组中
usermod -a -G GroupName UserName  #用户组 用户名,-a 代表 append,也就是将用户添加到新用户组中而不必离开原有的其他用户组

chmod:修改文件或者文件夹的权限
chmod -R 770 /home/user0/  # -R是目录下所有文件

如要将/home/user0目录的用户和用户组都修改为user0,www用户划分到user0组,并让user0组具有可读和可执行的权限,可以这样操作:
chown -R user0:user0
usermod -a -G user0 www
chmod -R 750 /home/user0

查看当前用户(www)是否具有读取和执行某.sh脚本权限的函数:

<?php
$ScriptPath = '/home/user0/test.sh';
var_dump(array(
     'file' => is_file($ScriptPath),
     'readable' => is_readable($ScriptPath),
     'executable' => is_executable($ScriptPath)
 ));
?>

参考文档:
Linux – chmod/chown命令与文件权限设置
Linux 访问文件 Permission denied 的原因

相关推荐