从 PHP 脚本执行 shell 脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17151946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Executing a shell script from a PHP script
提问by nmadhok
I want to execute a Bash script present on the system from a PHP script. I have two scripts present on the system. One of them is a PHP script called client.php
present at /var/www/html
and the other is a Bash script called testscript
present at /home/testuser
.
我想从 PHP 脚本执行系统上存在的 Bash 脚本。我在系统上有两个脚本。其中一个是名为client.php
present at的 PHP 脚本/var/www/html
,另一个是名为testscript
present at的 Bash 脚本/home/testuser
。
My client.php script looks like
我的 client.php 脚本看起来像
<?php
$message=shell_exec("/home/testuser/testscript 2>&1");
print_r($message);
?>
My testscript looks like
我的测试脚本看起来像
#!/bin/bash
echo "Testscript run succesful"
When i do the following on terminal
当我在终端上执行以下操作时
php client.php
I get the following output on terminal
我在终端上得到以下输出
Testscript run successful
But when i open the page at
但是当我打开页面时
http://serverdomain/client.php
I get the following output
我得到以下输出
sh: /home/testuser/testscript: Permission denied
I get this error even after I did chmod +x testscript.
How do I get it to work from the browser? Please help.
即使在我执行 chmod +x testscript 之后,我也会收到此错误。
我如何让它从浏览器工作?请帮忙。
采纳答案by Panama Hyman
I would have a directory somewhere called scripts under the WWW folder so that it's not reachable from the web but is reachable by PHP.
我会在 WWW 文件夹下有一个名为 scripts 的目录,这样它就不能从网络访问,但可以通过 PHP 访问。
e.g. /var/www/scripts/testscript
例如 /var/www/scripts/testscript
Make sure the user/group for your testscript
is the same as your webfiles. For instance if your client.php
is owned by apache:apache
, change the bash script to the same user/group using chown
. You can find out what your client.php
and web files are owned by doing ls -al
.
确保您的用户/组与您testscript
的网络文件相同。例如,如果您client.php
的所有者为apache:apache
,请使用 将 bash 脚本更改为相同的用户/组chown
。您可以client.php
通过执行ls -al
.
Then run
然后运行
<?php
$message=shell_exec("/var/www/scripts/testscript 2>&1");
print_r($message);
?>
EDIT:
编辑:
If you really want to run a file as root from a webserver you can try this binary wrapper below. Check out this solution for the same thing you want to do.
如果您真的想从网络服务器以 root 身份运行文件,您可以尝试下面的二进制包装器。对于您想要做的同样的事情,请查看此解决方案。
回答by Craig Hesling
Without really knowing the complexity of the setup, I like the sudo route. First, you must configure sudo to permit your webserver to sudo run the given command as root. Then, you need to have the script that the webserver shell_exec's(testscript) run the command with sudo.
在不真正了解设置的复杂性的情况下,我喜欢 sudo 路线。首先,您必须配置 sudo 以允许您的网络服务器以 root 身份 sudo 运行给定的命令。然后,您需要让 web 服务器 shell_exec(testscript) 使用 sudo 运行命令的脚本。
For A Debian box with Apache and sudo:
对于带有 Apache 和 sudo 的 Debian 机器:
Configure sudo:
As root, run the following to edit a new/dedicated configuration file for sudo:
visudo -f /etc/sudoers.d/Webserver
(or whatever you want to call your file in
/etc/sudoers.d/
)Add the following to the file:
www-data ALL = (root) NOPASSWD: <executable_file_path>
where
<executable_file_path>
is the command that you need to be able to run as root with the full path in its name(say/bin/chown
for the chownexecutable). If the executable will be run with the same arguments every time, you can add its arguments right after the executable file's name to further restrict its use.For example, say we always want to copy the same file in the /root/ directory, we would write the following:
www-data ALL = (root) NOPASSWD: /bin/cp /root/test1 /root/test2
Modify the script(testscript):
Edit your script such that
sudo
appears before the command that requires root privileges(saysudo /bin/chown ...
orsudo /bin/cp /root/test1 /root/test2
). Make sure that the arguments specified in the sudo configuration file exactly match the arguments used with the executable in this file. So, for our example above, we would have the following in the script:sudo /bin/cp /root/test1 /root/test2
配置sudo:
以 root 身份运行以下命令来编辑 sudo 的新/专用配置文件:
visudo -f /etc/sudoers.d/Webserver
(或任何您想在 中调用文件的内容
/etc/sudoers.d/
)将以下内容添加到文件中:
www-data ALL = (root) NOPASSWD: <executable_file_path>
这里
<executable_file_path>
是你必须能够以root身份在其名称的完整路径运行命令(假设/bin/chown
为CHOWN可执行文件)。如果可执行文件每次都使用相同的参数运行,您可以在可执行文件的名称后立即添加其参数以进一步限制其使用。例如,假设我们总是想复制 /root/ 目录中的同一个文件,我们将编写以下内容:
www-data ALL = (root) NOPASSWD: /bin/cp /root/test1 /root/test2
修改脚本(testscript):
编辑您的脚本,使其
sudo
出现在需要 root 权限的命令之前(例如sudo /bin/chown ...
或sudo /bin/cp /root/test1 /root/test2
)。确保 sudo 配置文件中指定的参数与此文件中的可执行文件使用的参数完全匹配。因此,对于我们上面的示例,我们将在脚本中包含以下内容:sudo /bin/cp /root/test1 /root/test2
If you are still getting permission denied, the script file and it's parent directories' permissions may not allow the webserver to execute the script itself. Thus, you need to move the script to a more appropriate directory and/or change the script and parent directory's permissions to allow execution by www-data(user or group), which is beyond the scope of this tutorial.
如果您仍然获得权限被拒绝,则脚本文件及其父目录的权限可能不允许网络服务器执行脚本本身。因此,您需要将脚本移动到更合适的目录和/或更改脚本和父目录的权限以允许 www-data(用户或组)执行,这超出了本教程的范围。
Keep in mind:
记住:
When configuring sudo, the objective is to permit the command in it's most restricted form. For example, instead of permitting the general use of the cpcommand, you only allow the cpcommand if the arguments are, say, /root/test1 /root/test2. This means that cp's arguments(and cp's functionality cannot be altered).
配置 sudo 时,目标是以最受限制的形式允许命令。例如,如果参数是/root/test1 /root/test2,则只允许cp命令,而不是允许cp命令的一般使用。这意味着cp的参数(和 cp 的功能不能改变)。
回答by Rob EatsEverything Delaney
I was struggling with this exact issue for three days. I had set permissions on the script to 755. I had been calling my script as follows.
我在这个确切的问题上挣扎了三天。我已将脚本的权限设置为 755。我一直按如下方式调用我的脚本。
<?php
$outcome = shell_exec('/tmp/clearUp.sh');
echo $outcome;
?>
My script was as follows.
我的脚本如下。
#!bin/bash
find . -maxdepth 1 -name "search*.csv" -mmin +0 -exec rm {} \;
I was getting no output or feedback. The change I made to get the script to run was to add a cd to tmp inside the script:
我没有得到任何输出或反馈。我为让脚本运行所做的更改是在脚本内向 tmp 添加一个 cd:
#!bin/bash
cd /tmp;
find . -maxdepth 1 -name "search*.csv" -mmin +0 -exec rm {} \;
This was more by luck than judgement but it is now working perfectly. I hope this helps.
这更多是靠运气而不是判断,但它现在工作得很好。我希望这有帮助。
回答by priyolahiri
It's a simple problem. When you are running from terminal, you are running the php file from terminal as a privileged user. When you go to the php from your web browser, the php script is being run as the web server user which does not have permissions to execute files in your home directory. In Ubuntu, the www-data user is the apache web server user. If you're on ubuntu you would have to do the following: chown yourusername:www-data /home/testuser/testscript chmod g+x /home/testuser/testscript
这是一个简单的问题。当您从终端运行时,您是以特权用户身份从终端运行 php 文件。当您从 Web 浏览器转到 php 时,php 脚本以 Web 服务器用户身份运行,该用户无权在您的主目录中执行文件。在 Ubuntu 中,www-data 用户是 apache 网络服务器用户。如果您使用的是 ubuntu,则必须执行以下操作: chown yourusername:www-data /home/testuser/testscript chmod g+x /home/testuser/testscript
what the above does is transfers user ownership of the file to you, and gives the webserver group ownership of it. the next command gives the group executable permission to the file. Now the next time you go ahead and do it from the browser, it should work.
上面所做的是将文件的用户所有权转让给您,并赋予网络服务器组所有权。下一个命令授予组对该文件的可执行权限。现在,下次您继续从浏览器执行此操作时,它应该可以工作。