如何在 PHP 中执行 shell 脚本?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5882650/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 22:47:04  来源:igfitidea点击:

How to execute a shell script in PHP?

phpshell

提问by Rakesh

I have a script in /var/www/myscript.shwhich creates folders and runs the command svn updatefor my projects. I need to execute this script by calling it in a PHP file in the browser (i.e. Localhost/test.php). I tried using functions shell_exec()and exec()but those did not work. I ran my shell script in terminal with su www-data && ./myscript.shand it worked. What else am I missing?

我在/var/www/myscript.sh 中有一个脚本,它创建文件夹并svn update为我的项目运行命令。我需要通过在浏览器中的 PHP 文件(即Localhost/test.php)中调用它来执行此脚本。我尝试使用函数shell_exec()exec()但那些没有用。我在终端中运行了我的 shell 脚本su www-data && ./myscript.sh,它工作正常。我还缺少什么?

<?php
$output = shell_exec("./myscript.sh");
?>


Update 5/4/2011:

2011 年 5 月 4 日更新:

I added www-data ALL=(ALL) NOPASSWD:ALLto /etc/sudoers and it works, but this is very insecure. Is there another way to do this?

我添加www-data ALL=(ALL) NOPASSWD:ALL到 /etc/sudoers 并且它有效,但这非常不安全。有没有另一种方法可以做到这一点?

回答by Residuum

Several possibilities:

几种可能:

  • You have safe mode enabled. That way, only exec()is working, and then only on executables in safe_mode_exec_dir
  • execand shell_execare disabled in php.ini
  • The path to the executable is wrong. If the script is in the same directory as the php file, try exec(dirname(__FILE__) . '/myscript.sh');
  • 您已启用安全模式。这样,只有exec()在工作,然后只在可执行文件safe_mode_exec_dir
  • execshell_exec在 php.ini 中被禁用
  • 可执行文件的路径错误。如果脚本与php文件在同一目录中,请尝试exec(dirname(__FILE__) . '/myscript.sh');

回答by Gabriel Poama-Neagra

You might have disabled the exec privileges, most of the LAMP packages have those disabled. Check your php.ini for this line:

您可能禁用了 exec 权限,大多数 LAMP 软件包都禁用了这些权限。检查你的 php.ini 这一行:

disable_functions = exec

And remove the exec, shell_exec entries if there are there.

并删除 exec、shell_exec 条目(如果有)。

Good Luck!

祝你好运!

回答by Pharaoh Tools

Residuum did provide a correct answer to how you should get shell exec to find your script, but in regards to security, there are a couple of points.

Residuum 确实为您应该如何让 shell exec 找到您的脚本提供了正确的答案,但在安全性方面,有几点。

I would imagine you don't want your shell script to be in your web root, as it would be visible to anyone with web access to your server.

我想您不希望您的 shell 脚本位于您的 Web 根目录中,因为任何可以通过 Web 访问您的服务器的人都可以看到它。

I would recommend moving the shell script to outside of the webroot

我建议将 shell 脚本移到 webroot 之外

    <?php
      $tempFolder = '/tmp';
      $webRootFolder = '/var/www';
      $scriptName = 'myscript.sh';
      $moveCommand = "mv $webRootFolder/$scriptName $tempFolder/$scriptName";
      $output = shell_exec($moveCommand);
    ?>

In regards to the:

关于:

i added www-data ALL=(ALL) NOPASSWD:ALL to /etc/sudoers works

我添加了 www-data ALL=(ALL) NOPASSWD:ALL 到 /etc/sudoers 工作

You can modify this to only cover the specific commands in your script which require sudo. Otherwise, if none of the commands in your sh script require sudo to execute, you don't need to do this at all anyway.

您可以修改它以仅涵盖脚本中需要 sudo 的特定命令。否则,如果您的 sh 脚本中的任何命令都不需要执行 sudo,则您根本不需要执行此操作。

Try running the script as the apache user (use the su command to switch to the apache user) and if you are not prompted for sudo or given permission denied, etc, it'll be fine.

尝试以 apache 用户身份运行脚本(使用 su 命令切换到 apache 用户),如果没有提示您输入 sudo 或授予权限被拒绝等,那就没问题了。

ie:

IE:

sudo su apache (or www-data)
cd /var/www
sh ./myscript


Also... what brought me here was that I wanted to run a multi line shell script using commands that are dynamically generated. I wanted all of my commands to run in the same shell, which won't happen using multiple calls to shell_exec(). The answer to that one is to do it like Jenkins - create your dynamically generated multi line of commands, put it in a variable, save it to a file in a temp folder, execute that file (using shell_exec in() php as Jenkins is Java), then do whatever you want with the output, and delete the temp file

另外......让我来到这里的是我想使用动态生成的命令运行多行shell脚本。我希望我的所有命令都在同一个 shell 中运行,使用多次调用 shell_exec() 不会发生这种情况。答案是像 Jenkins 那样做 - 创建动态生成的多行命令,将其放入变量中,将其保存到临时文件夹中的文件中,执行该文件(使用 shell_exec in() php 作为 Jenkins Java),然后对输出做任何你想做的事情,并删除临时文件

... voila

……瞧

回答by Babak D

If you are having a small script that you need to run (I simply needed to copy a file), I found it much easier to call the commands on the PHP script by calling

如果您有一个需要运行的小脚本(我只需要复制一个文件),我发现通过调用调用 PHP 脚本上的命令要容易得多

exec("sudo cp /tmp/testfile1 /var/www/html/testfile2");

and enabling such transaction by editing (or rather adding) a permitting line to the sudoers by first calling sudo visudoand adding the following line to the very end of it

并通过首先调用sudo visudo以下行并将其添加到 sudoers 的最后一行来编辑(或添加)允许行来启用此类事务

www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/testfile1 /var/www/html/testfile2

All I wanted to do was to copy a file and I have been having problems with doing so because of the root password problem, and as you mentioned I did NOT want to expose the system to have no password for all root transactions.

我想要做的就是复制一个文件,但由于 root 密码问题,我一直在这样做时遇到问题,正如你提到的,我不想让系统暴露所有 root 事务没有密码。