2010-09-03 9 views
8

Imaginez une application Web qui permet à un utilisateur connecté d'exécuter une commande shell sur le serveur Web en appuyant sur un bouton. Ceci est relativement simple dans la plupart des langues via certains outils de bibliothèque OS standard. Mais si cette commande est longue, vous ne voulez pas que votre interface se bloque. Encore une fois, il est relativement facile d'utiliser une sorte de processus d'arrière-plan ou de mettre la commande à exécuter dans une file d'attente de messages (et peut-être d'enregistrer la sortie et l'état pour une consommation ultérieure). Il suffit de revenir rapidement en économisant, nous allons courir cela et revenir vers vous.Quelle est la meilleure façon d'exécuter des commandes shell à partir d'une interface Web?

Ce que je voudrais faire est d'afficher la sortie de la commande de shell Web déclenchée par l'interface utilisateur en l'occurrence. Donc, défilement vertical du texte comme lors de l'exécution dans un terminal. J'ai une vague idée de la façon dont je pourrais aborder cela, en diffusant la sortie sur un WebSocket peut-être et en imprimant simplement la sortie à l'écran.

Ce que je voudrais poser est la suivante:

Y at-plugins, les bibliothèques ou les applications qui le font déjà. Quelque chose que je peux utiliser ou lire la source de. Idéalement, un outil open source python/django ou ruby ​​/ rails, mais d'autres piles seraient intéressantes aussi.

Répondre

1

Donc, j'ai essayé de répondre à ma propre question avec le code que je ne pourrais pas » Je ne trouve rien qui corresponde à la facture. J'espère que c'est utile à tous ceux qui rencontrent le même problème.

Redbeard 0X0A m'a indiqué dans la direction générale, j'ai été en mesure d'obtenir un stand le long de l'écriture ruby ​​faire ce que je voulais en utilisant popen. L'extension de ceci à l'utilisation de EventMachine (car elle fournissait un moyen pratique d'écrire un serveur websocket) et l'utilisation de sa méthode popen intégrée ont résolu mon problème.

Plus de détails ici http://morethanseven.net/2010/09/09/Script-running-web-interface-with-websockets.html et le code à http://github.com/garethr/bolt/

1

Je ne sais pas si c'est ce que vous voulez, mais il existe des clients ssh sur le Web. Si vous vous souciez de la sécurité et que vous voulez vraiment un retour dynamique, vous pouvez regarder dans la comète ou simplement avoir un cadre avec sa propre session http qui ne se termine pas tant que l'impression n'est pas terminée.

1

Je n'ai pas entendu parler de toutes les bibliothèques qui font cela, mais vous aurez besoin de configurer la commande du système et appeler au système. Vous devrez ensuite "pomper" les entrées standard sysout et syserr et rediriger ces données vers votre client Web. À titre d'exemple pour ce type de problème, consultez les extraits de code sur la façon dont les gens utilisent ruby ​​/ python/etc pour transcoder une vidéo, par exemple http://kpumuk.info/ruby-on-rails/encoding-media-files-in-ruby-using-ffmpeg-mencoder-with-progress-tracking/ - mon exemple a été tiré de cet article de blogue.

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 

Je ne sais pas si cet exemple tire des données à la fois sysout et syserr, mais vous aurez certainement besoin d'être tirer des données de ces deux interfaces, généralement si le tampon se remplit, la commande exécution pourrait accrocher ou échouer (j'ai éprouvé ceci avec Python). Cette méthode sera également différente si la seule chose que vous faites est de retourner line au client Web - dans un terminal, l'indicateur de progression de ffmpeg/mencoder reste stationnaire sur la ligne du bas, mais cette méthode vous donnera une longue liste d'indicateurs de progression mises à jour. Pipe line sur votre terminal et vous verrez de quoi je parle.

+0

Merci. Simplifier cette approche me donne le backend je pense - en utilisant IO.popen retournera ligne par ligne la sortie comme il arrive. Ensuite, juste besoin de l'obtenir à l'interface. – Garethr

0

Certainement pas la meilleure façon d'exécuter des commandes shell, mais probablement le plus facile:

#!/bin/sh 

echo Content-Type: text/plain 
echo 

/usr/bin/uptime 

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

+0

en cours d'exécution de la commande est moins le problème, je suis plus intéressé à montrer la sortie de la ligne de commande par ligne comme il arrive dans l'interface web – Garethr

0

Jetez un oeil à Galaxy (en ligne demo) ou Yabi. À l'exception de l'obligation de montrer la sortie pendant le travail, ils sont tous les deux d'excellentes solutions pour cela! Ils sont aussi tous deux écrits en Python (et Yabi même en django).

Ils ont tous deux été conçus en tenant compte de la bioinformatique, mais ils sont tous les deux des outils généraux de gestion de travaux et de flux de travaux. Ils vous permettent de spécifier des paramètres dans une interface Web, voir les tâches en attente/en cours d'exécution/terminées dans une colonne séparée et, une fois les travaux terminés, d'inspecter les détails et les résultats ou de réexécuter le travail avec des paramètres éventuellement modifiés .

Galaxy est le plus facile à installer. L'installation Galaxy se résume à télécharger et exécuter « sh run.sh »), et en ajoutant votre propre bout outil vers le bas pour créer un fichier XML dans la ligne 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> 

... et placez-le dans le répertoire/dossier tools, et ajoutez une ligne dans le fichier tool_conf.xml pour indiquer la galaxie de votre nouvel outil (Vous pouvez également vous débarrasser des outils bioinformatics, afin qu'ils ne gâchent pas votre menu d'outils).

Yabi est plus compliqué à installer (voir le fichier readme), mais le processus peut être fluide si vous êtes sur le bon type de système. D'un autre côté, il vous permet même de faire la configuration de l'outil dans l'interface web, plutôt que comme un fichier XML comme dans Galaxy.

Galaxy est toujours celui qui a la plus grande communauté, ce qui se reflète dans le nombre de fonctionnalités/outils déjà intégrés (voir le toolshed pour les outils partagés/wrapper).

Questions connexes