sudo在php exec()

时间:2010-07-03 23:32:53

标签: php linux sudo

我不知道这笔交易是什么......

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

这在终端中工作正常,但是当我通过PHP的exec()执行时却没有。什么都没发生。控制台说

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

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

  • %admin ALL=(ALL) ALL
  • 中撰写/etc/sudoers
  • proc_open()代替exec()

这些似乎都没有起作用,因此驱使我CrAzY!

基本上,是否有一种明确的方式让PHP执行一个简单的终端命令?

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

8 个答案:

答案 0 :(得分:15)

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

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

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

Defaults    requiretty

答案 1 :(得分:15)

如果有人仍然需要这个。您可以使用root密码编写纯文本文件,例如〜。/ .sudopass / sudopass.secret 。假设root密码是'12345'。您只需'12345'即可创建〜。/。sudopass / sudopass.secret

12345

然后你执行以下操作:

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

请记住仅在受控环境中使用此功能。

答案 2 :(得分:8)

我认为您可以使用visudo这样的内容对用户和命令进行特定访问:

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

并使用php:

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

假设nobody用户正在运行apache。

答案 3 :(得分:4)

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 $1
    
  2. myMount.bash:

    #!/bin/bash
    function error_exit
    {
      echo "Wrong parameter" 1>&2
      exit 1
    }
    ..........
    
  3. oc,您希望在没有root权限的情况下从根级别运行脚本,以创建和修改/etc/sudoers.d/mount文件:

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

    别忘了chmod:

    sudo chmod 0440 /etc/sudoers.d/mount
    

答案 4 :(得分:1)

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

答案 5 :(得分:0)

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

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

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

答案 6 :(得分:0)

在尝试exec()后端命令并在Web服务器错误日志中也获得no tty present and no askpass program specified时,我遇到了类似的情况。原始(错误)代码:

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

bash包装器解决了此问题,例如:

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

不确定是否在每种情况下都可以使用。另外,请确保在my_command部分应用适当的引号/转义规则。

答案 7 :(得分:0)

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

          • killProcess.php