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”修改也行
开启后,正常自己网站目录里面的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 的原因