Linux php exec() 中的 sudo

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

sudo in php exec()

phplinuxsudo

提问by pop850

I don't know what the deal is here…

我不知道这里有什么交易......

So I want to run an applescript: sudo osascript myscript.scpt

所以我想运行一个applescript: sudo osascript myscript.scpt

This works fine in the terminal, but not when I execute it via PHP's exec(); nothing happens. The console says

这在终端中工作正常,但当我通过 PHP 执行它时就不行了exec();没发生什么事。控制台说

no tty present and no askpass program specified ; TTY=unknown ; …

I did my research, and it seems I'm missing the password for the sudocommand. I tried a couple different ways to get around this, including:

我做了我的研究,似乎我缺少sudo命令的密码。我尝试了几种不同的方法来解决这个问题,包括:

  • writing %admin ALL=(ALL) ALLin /etc/sudoers
  • and proc_open()instead of exec()
  • %admin ALL=(ALL) ALL/etc/sudoers
  • proc_open()不是exec()

none of which seem to be working, consequently driving me CrAzY!

这些似乎都不起作用,因此让我疯狂!

So basically, is there a clear-cut way to get PHP to execute a simple terminal command?

所以基本上,有没有一种明确的方法让 PHP 执行一个简单的终端命令?

EDIT: to clarify, myscript.scptis a simple appleScript that changes the onscreen UI (for a larger project). In theory, simply osascript myscript.scptshould be enough, however the sudois for some reason necessary to invoke someresponse from the system. If the sudocould be somehow eliminated, I don't think I would be having this permissions problem.

编辑:澄清myscript.scpt一下,是一个简单的 appleScript,它改变了屏幕 UI(对于更大的项目)。从理论上讲,简单osascript myscript.scpt应该就足够了,但是sudo出于某种原因需要调用系统的某些响应。如果sudo可以以某种方式消除,我认为我不会遇到这个权限问题。

回答by tomit

It sounds like you need to set up passwordless sudo. Try:

听起来您需要设置无密码 sudo。尝试:

%admin ALL=(ALL) NOPASSWD: osascript myscript.scpt

Also comment out the following line (in /etc/sudoers via visudo), if it is there:

还注释掉以下行(通过 visudo 在 /etc/sudoers 中),如果它在那里:

Defaults    requiretty

回答by scabezas

If anyone still requires this. You can write a plain text file, say ~./.sudopass/sudopass.secret, with the root password there. Let's say the root password is '12345'. You create ~./.sudopass/sudopass.secretwith only '12345'as its content:

如果有人还需要这个。你可以写一个纯文本文件,比如~./.sudopass/sudopass.secret,在那里有 root 密码。假设 root 密码是“12345”。您创建~./.sudopass/sudopass.secret ,其中仅包含'12345'作为其内容:

12345

And then you do the following:

然后您执行以下操作:

exec('sudo -u root -S {{ your command }} < ~/.sudopass/sudopass.secret');

Remember to use this only in controlled environments.

请记住仅在受控环境中使用它。

回答by lisu

php: the bash console is created, and it executes 1st script, which call sudo to the second one, see below:

php:创建 bash 控制台,并执行第一个脚本,该脚本将 sudo 调用到第二个脚本,如下所示:

$dev = $_GET['device'];
$cmd = '/bin/bash /home/www/start.bash '.$dev;
echo $cmd;
shell_exec($cmd);
  1. /home/www/start.bash

    #!/bin/bash
    /usr/bin/sudo /home/www/myMount.bash 
    
  2. myMount.bash:

    #!/bin/bash
    function error_exit
    {
      echo "Wrong parameter" 1>&2
      exit 1
    }
    ..........
    
  1. /home/www/start.bash

    #!/bin/bash
    /usr/bin/sudo /home/www/myMount.bash 
    
  2. myMount.bash:

    #!/bin/bash
    function error_exit
    {
      echo "Wrong parameter" 1>&2
      exit 1
    }
    ..........
    

oc, you want to run script from root level without root privileges, to do that create and modify the /etc/sudoers.d/mount file:

oc,你想在没有 root 权限的情况下从 root 级别运行脚本,为此创建和修改 /etc/sudoers.d/mount 文件:

www-data ALL=(ALL:ALL) NOPASSWD:/home/www/myMount.bash

dont forget to chmod:

不要忘记chmod:

sudo chmod 0440 /etc/sudoers.d/mount

回答by Ezequiel Hdez.

I think you can bring specific access to user and command with visudosomething like this:

我认为您可以通过以下方式对用户和命令进行特定访问visudo

nobody ALL = NOPASSWD: /path/to/osascript myscript.scpt

and with php:

并使用 php:

@exec("sudo /path/to/osascript myscript.scpt ");

supposing nobodyuser is running apache.

假设nobody用户正在运行 apache。

回答by MerlinTheMagic

I recently published a project that allows PHP to obtain and interact with a real Bash shell. Get it here: https://github.com/merlinthemagic/MTSThe shell has a pty (pseudo terminal device, same as you would have in i.e. a ssh session), and you can get the shell as root if desired. Not sure you need root to execute your script, but given you mention sudo it is likely.

我最近发布了一个项目,允许 PHP 获取真正的 Bash shell 并与之交互。在此处获取:https: //github.com/merlinthemagic/MTSshell 有一个 pty(伪终端设备,与 ssh 会话中的设备相同),如果需要,您可以以 root 身份获取 shell。不确定您是否需要 root 来执行您的脚本,但鉴于您提到 sudo 很可能。

After downloading you would simply use the following code:

下载后,您只需使用以下代码:

$shell    = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1  = $shell->exeCmd('/path/to/osascript myscript.scpt');

回答by Keshav Maheshwari

Run sudo visudocommand then set -%sudo ALL=(ALL:ALL)to %sudo ALL=(ALL:ALL) NOPASSWD: ALLit will work.

运行sudo visudo命令然后设置-%sudo ALL=(ALL:ALL)%sudo ALL=(ALL:ALL) NOPASSWD: ALL它会起作用。

回答by Balage

I had a similar situation trying to exec()a backend command and also getting no tty present and no askpass program specifiedin the web server error log. Original (bad) code:

我在尝试执行exec()后端命令并进入no tty present and no askpass program specifiedWeb 服务器错误日志时遇到了类似的情况。原始(坏)代码:

$output = array();
$return_var = 0;
exec('sudo my_command', $output, $return_var);

A bashwrapper solved this issue, such as:

一个bash包装器解决了这个问题,例如:

$output = array();
$return_var = 0;
exec('sudo bash -c "my_command"', $output, $return_var);

Not sure if this will work in every case. Also, be sure to apply the appropriate quoting/escaping rules on my_commandportion.

不确定这是否适用于所有情况。此外,请务必对部分应用适当的引用/转义规则my_command

回答by Sanjay Kumar N S

The best secure method is to use the crontab. ie Save all your commands in a database say, mysql table and create a cronjob to read these mysql entreis and execute via exec() or shell_exec(). Please read this linkfor more detailed information.

最好的安全方法是使用 crontab。即,将所有命令保存在数据库中,例如 mysql 表并创建一个 cronjob 以读取这些 mysql entreis 并通过 exec() 或 shell_exec() 执行。请阅读此链接以获取更多详细信息。

          • killProcess.php
          • 杀进程.php