【问题标题】:Running server-side Bash scripts through CGI通过 CGI 运行服务器端 Bash 脚本
【发布时间】:2014-12-04 19:47:57
【问题描述】:

所需信息: 我正在使用来自 yum repo 的 httpd 的家庭 PC 网络服务器 Fedora 20 运行它。 我从http://www.instructables.com/id/Simple-linux-commands-from-a-web-page/ 获取了我的 .cgi 文件的基本版本,并一直在尝试根据我的需要对其进行修改。

我的问题 - 我可以很容易地让 cgi 脚本运行 uname、lspci、ls 以及 /usr/bin 文件夹中仅显示文本的任何脚本。 但是,我不能运行实际执行某些操作的脚本。例如,我无法让 cgi 运行“rhythmbox-client --next”来跳过 Rhythmbox 媒体播放器上的歌曲。

我的意图:我为我的朋友 ventrilo 服务器运行一个“音乐机器人”,我想为他们提供(受密码保护的)方式来从网络访问该机器人、更改歌曲、将歌曲添加到播放队列中,等等等等。

我需要的功能(我都无法使用)是: 下一首歌曲 (rhythmbox-client --next) 上一首歌 (rhythmbox-client --previous) 将歌曲添加到队列(rhythmbox-clinet --enqueue NAME) 清除歌曲队列(rhythmbox-client --clear-queue 显示当前播放的歌曲(rhythmbox-client --print-playing) 显示电脑上的歌曲列表(ls /home/user/Music | grep ".mp3")

尽我所能,我无法让这些东西发挥作用。我也试过用 Banshee 代替节奏盒,但同样的问题。

假设执行命令的脚本部分如下: 回声“” echo "精英音乐机器人控制面板" PATH="/bin:/usr/bin:/usr/ucb:/usr/opt/bin" 导出 $PATH 回声“” 回声“”

# test if any parameters were passed
if [ $CMD ]
then
  case "$CMD" in
    BotInfo)
    echo "<pre>"
      /bin/BotInfo
    echo "System Name:" `/bin/uname -n`
      echo "</pre>"
      ;;

    next)
      echo "Skipped to the next song."
      /bin/rhythmbox-client --next
      ;;

    back)
      echo "Repeating the previous song. <pre>"
      /bin/rhythmbox-client --previous
      echo "</pre>"
      ;;

playing)
      echo "The current song playing is... <pre>"
      rhythmbox-client --print-playing
      echo "</pre>"
      ;;

queue)
      echo "The requested song has been added to the queue. <pre>"
      rhythembox-client --enqueue $QUEUE_SONG
      echo "</pre>"
      ;;

       rating)
          echo "The rating of the current song has been set to $RATING. <pre>"
          /bin/rhythmbox-client --set-rating $RATING
          echo "</pre>"
          ;;
ls)
    echo "<pre>"
    list=`ls /home/USER/Music | grep ".mp3"`
    echo "$list"
    echo "</pre>"
    ;;
     *)
      echo "Unknown command $CMD<br>"
      ;;
  esac
fi

第一个是显示系统时间(日期)、cpuinfo、meminfo 等的简单脚本,它确实可以工作。但是其他人没有。

我已经尝试将 bash 命令运行为

echo "$(command)"

对于打印播放,我尝试过这样做:

playing=`rhythmbox-client --print-playing`
echo "$playing" 

我也尝试过创建一个脚本:

#!/bin/bash
echo "This command worked!"
rhythmbox-client --next

我将 rhynext 命名为 chmod +x 并移至 /usr/bin,当在终端中运行时它可以工作,当告诉 cgi 执行 /usr/bin/rhynext 时它什么也不做。

请帮忙。

我很聪明,可以对代码进行逆向工程,如果您可以简单地给我一个可行的代码段/示例,我很可能能够将其转换为我的用途。提前致谢。

编辑:以 apache 用户身份为 Banshee 运行“下一个”脚本时..

sudo -u apache /usr/bin/next
[sudo] password for OMMITED: 
Unhandled Exception: System.UnauthorizedAccessException: Access to the path "/usr/share/httpd/.config" is denied.
  at System.IO.Directory.CreateDirectoriesInternal (System.String path) [0x00000] in <filename unknown>:0 
  at System.IO.Directory.CreateDirectory (System.String path) [0x00000] in <filename unknown>:0 
  at System.IO.DirectoryInfo.Create () [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) System.IO.DirectoryInfo:Create ()
  at System.IO.Directory.CreateDirectoriesInternal (System.String path) [0x00000] in <filename unknown>:0 
  at System.IO.Directory.CreateDirectory (System.String path) [0x00000] in <filename unknown>:0 
  at Hyena.Paths.InitializePaths () [0x00000] in <filename unknown>:0 
  at Hyena.Paths.set_ApplicationName (System.String value) [0x00000] in <filename unknown>:0 
  at Banshee.ServiceStack.Application.InitializePaths () [0x00000] in <filename unknown>:0 
  at Booter.Booter.Main () [0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.UnauthorizedAccessException: Access to the path "/usr/share/httpd/.config" is denied.
  at System.IO.Directory.CreateDirectoriesInternal (System.String path) [0x00000] in <filename unknown>:0 
  at System.IO.Directory.CreateDirectory (System.String path) [0x00000] in <filename unknown>:0 
  at System.IO.DirectoryInfo.Create () [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) System.IO.DirectoryInfo:Create ()
  at System.IO.Directory.CreateDirectoriesInternal (System.String path) [0x00000] in <filename unknown>:0 
  at System.IO.Directory.CreateDirectory (System.String path) [0x00000] in <filename unknown>:0 
  at Hyena.Paths.InitializePaths () [0x00000] in <filename unknown>:0 
  at Hyena.Paths.set_ApplicationName (System.String value) [0x00000] in <filename unknown>:0 
  at Banshee.ServiceStack.Application.InitializePaths () [0x00000] in <filename unknown>:0 
  at Booter.Booter.Main () [0x00000] in <filename unknown>:0 

【问题讨论】:

  • 您是否尝试将 stderr 重定向到文件(以查看是否出现任何错误消息)?
  • /bin/rhythmbox-client 可能希望连接到当前用户的节奏盒 dbus 接口,这个 cgi 将无法做到这一点。您可能需要手动公开正确的 dbus 会话。
  • 测试时,以 apache 用户身份运行脚本(例如sudo -u www-data ./yourscript)。
  • Etan - 我该怎么做,因为我很确定您对此是正确的,因为当我通过 ssh 登录时,我必须在运行此类命令之前运行 dbus 脚本。另一个人 - 我做到了,我从中得到了一大堆错误。更新原始问题以显示错误
  • 新开发 - 我拥有的 ls 命令,如果我将 apache 用户更改为我的用户名和用户组,我知道这是不可接受的,但我想看看如果我这样做会发生什么,所以也许这对于其中的一些来说也是一个权限问题?我将如何允许 apache 用户查看我的 ls 音乐文件夹?另外 - 有没有办法让 ls 命令列出也在所选目录的子目录中的文件?

标签: linux apache bash cgi


【解决方案1】:

问题源于节奏盒客户端希望连接到当前用户的 dbus 会话以收集节奏盒信息/发出命令。 (感谢 Etan Reisner 指出这一点)

在网上搜索了一下之后,我找到了解决方案。创建2个文件,一个用于在登录时将当前用户的dbus会话地址保存到一个临时文件中,另一个用于调用dbus地址并通过它路由CGI命令。

文件 1:保留在所需文件夹中,添加到开始项目,生成可执行文件 (chmod +x) 名称“Get.DBus.sh”

#!/bin/bash
set | grep DBUS_SESSION_BUS_ADDRESS > ~/.DBUS_temp

文件 2:生成可执行文件,移动到 /usr/bin,生成可执行文件 (chmod+x) 名称“Run.DBus.sh”

#!/bin/bash
source /home/USER/.DBUS_temp
export DBUS_SESSION_BUS_ADDRESS
$*

在 CGI 中更改所需命令的执行命令 from..

command)
  /bin/command
;;

command)
 /bin/RunDBus.sh /bin/command
;;

问题解决了。所有命令都按预期工作。

感谢大家的帮助,虽然这是 DBus 问题,但永远不会有 XD

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 2016-12-08
    • 2013-03-30
    • 2018-01-30
    相关资源
    最近更新 更多