45

我不知道这里的交易是什么……</p>

所以我想运行一个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()

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

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

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

4

8 回答 8

18

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

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

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

Defaults    requiretty
于 2010-07-03T23:46:16.770 回答
8

我认为您可以通过以下方式为用户和命令带来特定的访问权限visudo

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

并使用 php:

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

假设nobody用户正在运行 apache。

于 2013-05-10T17:24:45.513 回答
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
    }
    ..........
    

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
于 2012-06-01T07:16:52.540 回答
1

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

于 2017-07-06T07:31:21.590 回答
1

我最近发布了一个项目,它允许 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');
于 2016-05-18T10:26:56.150 回答
0

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

          • killProcess.php
于 2019-02-06T10:16:07.863 回答
0

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

$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部分应用适当的引用/转义规则。

于 2018-11-13T21:25:49.987 回答
0

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

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

于 2022-01-07T09:38:16.337 回答