从基于Web的界面运行shell命令的最佳方式是什么?

问题描述:

想象一下,一个web应用程序允许登录的用户在按下按钮时在web服务器上运行shell命令。在大多数语言中,这通过一些标准的库操作系统工具相对简单。从基于Web的界面运行shell命令的最佳方式是什么?

但是,如果该命令长时间运行,你不希望你的用户界面挂起。同样,使用某种后台进程或者将命令执行到消息队列中可能相对容易处理(也可能将输出和状态保存在某处供以后使用)。只需快速返回就可以运行,并返回给您。

我想要做的是显示所述web ui触发的shell命令的输出,其发生在。所以垂直滚动文本就像在终端中运行一样。

我有一个模糊的想法,我可能会如何处理这个问题,将输出流式传输到websocket,也许只是将输出打印到屏幕上。

我想什么要问的是:

是他们已经做任何插件,库或应用程序。我可以使用的东西或阅读的来源。理想情况下,一个开源的python/django或ruby/rails工具,但其他堆栈也会很有趣。

于是,我试着回答我的问题与代码,我不能”找到任何符合法案的东西。希望对遇到同样问题的任何人都有用。

Redbeard 0X0A指向我的大方向,我能够得到一个红宝石脚本的立场,做我想用popen做的事情。将其扩展到使用EventMachine(因为它提供了编写WebSocket服务器的便捷方式)并使用它内置的popen方法解决了我的问题。

这里http://morethanseven.net/2010/09/09/Script-running-web-interface-with-websockets.html更多细节,并在http://github.com/garethr/bolt/

我不确定它是否是你想要的,但有一些基于Web的ssh客户端。如果您关心安全性,并且只是想获得动态反馈,那么您可以查看彗星,或者拥有一个拥有自己的http会话的框架,该会话在完成打印之前不会结束。

基于Web的ssh客户端可以工作,进入主机(这里有java ssh客户端)。

Ruby有一个基于网络的终端: http://tryruby.org(链接到源是在页面的底部)。 您也可以通过JRuby中嵌入红宝石:http://tim.lossen.de/2007/03/jruby/applet.html http://github.com/jruby/jruby/blob/master/samples/irb-applet.html

我没有听说这样做的任何库,但你需要设置系统命令,调出系统。然后,您需要“泵”sysout和syserr标准输入,并将该数据传回给您的Web客户端。

作为这种风格问题的一个例子,请查看人们如何使用ruby/python/etc对视频进行代码转换的代码snippits,即http://kpumuk.info/ruby-on-rails/encoding-media-files-in-ruby-using-ffmpeg-mencoder-with-progress-tracking/ - 我的示例来自此博客帖子。

class MediaFormatException < StandardError 
end 

def execute_mencoder(command) 
    progress = nil 
    IO.popen(command) do |pipe| 
    pipe.each("r") do |line| 
     if line =~ /Pos:[^(]*(s*(d+)%)/ 
     p = $1.to_i 
     p = 100 if p > 100 
     if progress != p 
      progress = p 
      print "PROGRESS: #{progress}n" 
      $defout.flush 
     end 
     end 
    end 
    end 
    raise MediaFormatException if $?.exitstatus != 0 
end 

我不知道这个例子从两个系统输出和SYSERR拉取数据,但你肯定会需要从两个这些接口的拉取数据,通常如果缓冲区已满,执行命令可能挂起或失败(我已经与Python经历了这一点)。如果你做的唯一的事情是返回line给网络客户端,这种方法也会看起来不同 - 在终端中,ffmpeg/mencoder的进度指示器在底线上保持不变,但是这种方法会给你一个长长的进度指示器列表更新。管道line到您的终端,你会看到我指的是什么。

+0

谢谢。简化这种方法会给我后端,我认为 - 使用IO.popen将逐行返回输出。然后只需要把它放到前端。 – Garethr 2010-09-04 12:10:37

当然不是最好的方式运行shell命令,但可能最简单的:

#!/bin/sh 

echo Content-Type: text/plain 
echo 

/usr/bin/uptime 

http://www.sente.cc/scripts/uptime.cgi

+0

运行该命令的问题较少,我更感兴趣的是在Web界面中显示命令行的输出 – Garethr 2010-09-04 11:55:43

代码看看Galaxy(在线demo)或Yabi

除了能够在作业运行期间显示输出的要求,它们都是优秀的解决方案!它们也都是Python写的(甚至在django上也是Yabi)。

它们都是以生物信息学为基础构建的,但实际上它们都是通用的工作流程/工作流程工具。

它们将允许您在Web界面中指定参数,在单独的列中查看排队/运行/完成的作业,并在作业完成后检查详细信息和结果,或重新运行作业,并可能更改参数。

Galaxy更容易安装。银河安装归结为下载并运行“SH run.sh”),并加入自己的工具归结为线创建的XML文件:

<tool id="mytool" name="My Tool" version="1.0.0"> 
    <description>Does this and that</description> 
    <command>somecommand --aparam $aparam</command> 
    <inputs> 
    <param name="aparam" type="text" label="A parameter"/> 
    </inputs> 
    <outputs> 
    <data name="outfile" format="tabular"/> 
    </outputs> 
</tool> 

...,并将其放置在/工具文件夹,然后在tool_conf.xml中添加一行来告诉你的新工具的星系(在那里你也可以摆脱生物信息学工具,所以它们不会搞乱你的工具菜单)。

Yabi安装起来比较复杂(请参阅自述文件),但如果您使用的是正确的系统,则该过程可能很顺利。另一方面,它甚至可以在Web界面中进行工具配置,而不是像银河那样的XML文件。

尽管Galaxy仍然是社区中最大的一个,但这反映在功能/已经集成的工具的数量上(请参阅共享工具/包装的toolshed)。

websocketd看起来像是一个完美的工具。