【问题标题】:Running command-line application from PHP as specific user以特定用户身份从 PHP 运行命令行应用程序
【发布时间】:2011-10-18 07:26:03
【问题描述】:

我在本地主机上运行 Apache。从以 www-user 身份运行的 PHP 脚本中,我想控制我机器上的 Rhythmbox 播放。到目前为止,我的 PHP 脚本中有一个简单的命令:

exec('rhythmbox-client --pause');

当我以我的身份从命令行运行它时效果很好,但如果它以 www-user 身份运行,我猜rhythmbox-client 不知道/无法访问我的 Rhythmbox 实例。

有没有一种简单的方法让 PHP 脚本以我的用户而不是 www-user 身份运行,或者告诉 rhythmbox-client 要控制哪个实例?

整个应用程序是,当我的手机摘机时,它会调用我的 PHP 脚本来暂停音乐,并在手机挂机时恢复播放。我喜欢 VoIP 电话!

解决方案: 感谢 Carpetsmoker 和 Tarek,我使用 sudo 作为答案,但有几个问题。为了克服它们,我做了以下事情:

创建了一个 bash 脚本来调用 rhythmbox-client。此 bash 脚本是在 PHP 中使用 sudo 执行的,如下面的答案中所述。不幸的是rhythmbox-client 不知道要控制什么环境,所以 bash 脚本是这样的:

#! /bin/bash
DBUS_ADDRESS=`grep -z DBUS_SESSION_BUS_ADDRESS /proc/*/environ 2> /dev/null| sed 's/DBUS/\nDBUS/g' | tail -n 1`
if [ "x$DBUS_ADDRESS" != "x" ]; then
        export $DBUS_ADDRESS
        /usr/bin/rhythmbox-client --pause
fi

现在 bash 脚本可以由 PHP 和 wwwuser 执行,我的手机可以暂停/播放我的音乐!

【问题讨论】:

  • 尝试以非 root 身份运行韵律箱客户端怎么样?
  • 您打算只在本地运行您的服务器吗? (也就是从不把它放到网上)
  • @afuzzyllama 是的,它只是在本地

标签: php exec


【解决方案1】:

一种解决方案是使用sudo(8)

exec('sudo -u myuser ls /');

显然,您需要设置sudo(8) 以允许运行您的网络服务器的用户调用它。使用visudo(8) 编辑 sudoers 文件,您可以使用如下内容:

wwwuser ALL=/usr/bin/rhythmbox-client

为了防止 Apache 能够运行其他命令并且 rythymbox 命令。

【讨论】:

  • 您好,感谢您的回答。我用visudo 编辑了/etc/sudoers,但是当我执行sudo -u myuser rhythmbox-client --pause 时,系统提示我输入wwwuser 密码。有什么办法可以避免这个实例的密码验证?
  • 改成wwwuser ALL=NOPASSWD: /usr/bin/rhythmbox-client
  • 谢谢我把它改成了wwwuser ALL=(ALL) NOPASSWD: /usr/bin/rhythmbox-client。如果我从命令行以 wwwuser 的身份运行它,它会很好用,但是我的 PHP 脚本在通过 Apache 调用时不会运行它:(
  • 感谢您的帮助,我在答案中发布了最终解决方案。毕竟不仅仅是用户权限!
  • @Carpetsmoker,Windows Server 怎么样?
【解决方案2】:

如果一个进程可以由任何用户运行,它就可以由 PHP 运行。例如fortune 命令

-rwxr-xr-x 1 root root 18816 Oct  1  2009 /usr/games/fortune

查看每个用户的x 权限。但这有时根本不起作用,您可能必须让用户 www-dataapache 等运行程序。您可以sudo www-data 并尝试运行该命令。如果它有效,那么 Apache/PHP 应该能够运行它。

【讨论】:

    【解决方案3】:

    就我而言,解决方案是这样的:

    1. 将此行添加到 sudoers 文件中:

      myuser ALL=(ALL) NOPASSWD: /usr/bin/prlctl
      _www ALL=(ALL) NOPASSWD: /usr/bin/prlctl # 重要!!!

    2. PHP中的EXEC()命令改为:

      exec("sudo -u myuser prlctl list -a", $out, $r);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-26
      • 1970-01-01
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 2019-12-09
      • 1970-01-01
      相关资源
      最近更新 更多