2010-09-03 22 views
8

Imagine una aplicación web que permite a un usuario que ha iniciado sesión ejecutar un comando de shell en el servidor web con solo presionar un botón. Esto es relativamente simple en la mayoría de los idiomas a través de algunas herramientas estándar de OS de biblioteca.¿Cuál es la mejor forma de ejecutar comandos de shell desde una interfaz basada en web?

Pero si ese comando es de larga ejecución, no quiere que su UI se bloquee. De nuevo, esto es relativamente fácil de manejar utilizando algún tipo de proceso en segundo plano o haciendo que el comando se ejecute en una cola de mensajes (y tal vez guardando el resultado y el estado en algún lugar para su posterior consumo). Solo regrese rápidamente ahorrando, lo correremos y le responderemos.

Lo que me gustaría hacer es mostrar la salida de dicho comando de shell web ui triggered como ocurre. Así que se desplaza verticalmente el texto como cuando se ejecuta en una terminal.

Tengo una vaga idea de cómo podría abordar esto, transmitir la salida a un websocket quizás y simplemente imprimir la salida a la pantalla.

Lo que me gustaría hacer es:

Son sus plugins, bibliotecas o aplicaciones que ya lo hacen. Algo que puedo usar o leer la fuente de. Lo ideal sería una herramienta de python/django o ruby ​​/ rails de código abierto, pero otras pilas también serían interesantes.

Respuesta

1

Por lo tanto, he tratado de responder a mi propia pregunta con código como no pude Encontrar algo que se adapte a la factura. Con suerte, es útil para cualquiera que se encuentre con el mismo problema.

Redbeard 0X0A me señaló en la dirección general, pude obtener una posición a lo largo de la secuencia de comandos de ruby ​​haciendo lo que quería con Popen. Ampliar esto para usar EventMachine (ya que proporcionaba una forma conveniente de escribir un servidor de websocket) y usar su método popen incorporado resolvió mi problema.

Más detalles aquí http://morethanseven.net/2010/09/09/Script-running-web-interface-with-websockets.html y el código en http://github.com/garethr/bolt/

1

No estoy seguro si es lo que quiere, pero hay algunos clientes ssh basados ​​en la web. Si te preocupa la seguridad y realmente solo quieres comentarios dinámicos, podrías mirar el cometa o simplemente tener un marco con su propia sesión http que no termina hasta que se termine de imprimir.

1

No he sabido de ninguna biblioteca que hacen esto, pero tendrá que configurar el comando del sistema y llamar al sistema. Luego tendrá que "bombear" las entradas estándar sysout y syserr y canalizar esos datos nuevamente a su cliente web.

Como ejemplo para este estilo de problema, busque snippits de código de cómo la gente usa ruby ​​/ python/etc para transcodificar un video, es decir, http://kpumuk.info/ruby-on-rails/encoding-media-files-in-ruby-using-ffmpeg-mencoder-with-progress-tracking/ - mi ejemplo fue tomado de esta publicación de blog.

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 

No sé si este ejemplo está tirando de datos tanto sysout y SYSERR, pero que sin duda necesita estar tirando datos tanto de esas interfaces, por lo general si el búfer se llena, el comando de ejecución podría colgar o fallar (he experimentado esto con Python). Este método también se verá diferente si lo único que hace es devolver line al cliente web - en un terminal, el indicador de progreso de ffmpeg/mencoder permanece estacionario en la línea inferior, pero este método le dará una larga lista de indicadores de progreso actualizaciones. Transmita line a su terminal y verá a qué me refiero.

+0

Gracias. La simplificación de este enfoque me da el backend, creo que con IO.popen se devolverá línea por línea la salida a medida que ocurra. Entonces solo necesitas llevarlo a la interfaz. – Garethr

0

duda no es el mejor forma de ejecutar comandos de shell, pero probablemente el más fácil:

#!/bin/sh 

echo Content-Type: text/plain 
echo 

/usr/bin/uptime 

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

+0

ejecutar el comando es un problema menor, estoy más interesado en mostrar el resultado del comando línea por línea como ocurre en la interfaz web – Garethr

0

Echa un vistazo a Galaxy (línea demo) o Yabi.

Excepto por el requerimiento de poder mostrar la salida durante la ejecución del trabajo, ¡ambas son soluciones excelentes para esto! También están escritos i Python (y Yabi incluso en django).

Ambos fueron construidos con bioinformática en mente, pero en realidad son herramientas generales de corredor de trabajo/flujo de trabajo.

Le permitirán especificar parámetros en una interfaz web, ver puestos de trabajo en cola/en ejecución/finalizados en una columna separada y, una vez finalizados, inspeccionar detalles y resultados, o volver a ejecutar el trabajo, posiblemente con parámetros modificados .

Galaxy es la más fácil de instalar. La instalación Galaxy se reduce a descargar y ejecutar "run.sh sh"), y añadiendo su propia herramienta se reduce a la creación de un archivo XML en la línea de:

<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> 

... y lo coloca en el directorio/carpeta de herramientas, y agregue una línea en tool_conf.xml para contarle a galaxy su nueva herramienta (allí también puede deshacerse de las herramientas de bioinformática, para que no dañen el menú de herramientas).

Yabi es más complicado de instalar (consulte el archivo Léame), pero el proceso puede ser sencillo si se encuentra en el tipo correcto de sistema. Por otro lado, le permite incluso hacer la configuración de la herramienta en la interfaz web, en lugar de hacerlo como un archivo XML como en Galaxy.

Galaxy todavía es la que tiene la comunidad más grande, lo que se refleja en la cantidad de características/herramientas ya integradas (Ver el toolshed para herramientas compartidas/envoltorio).

Cuestiones relacionadas