php exec() 中的 sudo

发布于 2024-09-08 02:51:23 字数 720 浏览 5 评论 0原文

我不知道这是怎么回事……

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

这在终端中运行良好,但当我通过 PHP 的 exec 执行它时则不行();什么也没发生。控制台说

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

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

  • 中编写 %admin ALL=(ALL) ALL
  • /etc/sudoersproc_open() code> 而不是 exec()

似乎都不起作用,因此让我感到CrAzY!

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

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

I don't know what the deal is here…

So I want to run an 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

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

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

  • writing %admin ALL=(ALL) ALL in /etc/sudoers
  • and proc_open() instead of 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?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

梦亿 2024-09-15 02:51:24

我认为直接调用 sudo 命令可能很困难,因为您正在将整个服务器设置为无需密码即可工作。
也许作为替代方案,您可以将 CRONjob 设置为 root 并监视标志文件。一旦标志文件存在,它将运行 osascript myscript.scpt,然后删除标志文件。
这样,从配置的角度来看,您可以保证 SUDO 的安全,并使服务器更安全。要运行该脚本,您只需触摸 PHP 中的标志文件。
当然,无论您运行 CRON 作业多少分钟,它都会导致延迟。这也意味着您必须将输出重定向到文件并拥有输出的异步监视器,但这是否存在问题将取决于您的应用程序。

但这是一种可以保护服务器的替代方案。

I think directly calling a sudo command might be difficult because you are setting up the whole server to work without a password.
Perhaps as an alternative you could setup a CRONjob as root and monitor a flag file. Once the flag file exists it will run the osascript myscript.scpt and then delete the flag file.
This way you will keep SUDO secure from a config point of view and the server safer. To run the script you just need to touch the flag file from PHP.
It would of course introduce a delay of however many minutes you running the CRON job. It would also mean that you would have to redirect the output to a file and have a async monitor of the output, but it will depend on your application if this is a problem or not.

But it is an alternative that might protect the server.

苍白女子 2024-09-15 02:51:23

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

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

如果存在以下行(通过 visudo 在 /etc/sudoers 中),也将其注释掉:

Defaults    requiretty

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

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

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

Defaults    requiretty
花开浅夏 2024-09-15 02:51:23

我认为你可以使用 visudo 为用户和命令带来特定的访问权限,如下所示:

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

并使用 php:

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

假设 nobody 用户正在运行 apache。

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

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

and with php:

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

supposing nobody user is running apache.

━╋う一瞬間旳綻放 2024-09-15 02:51:23

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
    函数错误_退出
    {
    echo "参数错误" 1>&2
    1号出口
    }
    …………

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

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

不要忘记 chmod:

sudo chmod 0440 /etc/sudoers.d/mount

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

$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
    }
    ..........
    

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

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

dont forget to chmod:

sudo chmod 0440 /etc/sudoers.d/mount
岁月无声 2024-09-15 02:51:23

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

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

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

I recently published a project that allows PHP to obtain and interact with a real Bash shell. Get it here: https://github.com/merlinthemagic/MTS
The 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.

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');
如何视而不见 2024-09-15 02:51:23

运行sudo visudo命令,然后将-%sudo ALL=(ALL:ALL)设置为%sudo ALL=(ALL:ALL) NOPASSWD: ALL< /code> 会起作用的。

Run sudo visudo command then set -%sudo ALL=(ALL:ALL) to %sudo ALL=(ALL:ALL) NOPASSWD: ALL it will work.

败给现实 2024-09-15 02:51:23

您也可以在实际使用 sudo 之前使用 passthru 来验证它:

passthru('sudo -v');
exec('sudo osascript myscript.scpt', $output, $status);

You can alternatively use passthru to validate sudo before you actually use it:

passthru('sudo -v');
exec('sudo osascript myscript.scpt', $output, $status);
萌酱 2024-09-15 02:51:23

我也遇到过类似的情况,尝试exec()后端命令,并且在网络服务器错误日志中也遇到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 部分应用适当的引用/转义规则。

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

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

A bash wrapper solved this issue, such as:

$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_command portion.

假情假意假温柔 2024-09-15 02:51:23

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

          • killProcess.php

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 link for more detailed information.

          • killProcess.php
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文