2012-04-03 9 views
1

Ich habe ein peinliches Problem mit dem Subprocess.call-Operator in Python für ein Skript. Ich muss ein Pipeline-Programm (bowtie) mehrmals ausführen und dann die Ausgabe auf verschiedene Arten verwenden. Zu diesem Zweck benutze ich die subprocess.call.Multpile stdin mit subprocess.call in Python (für Bowtie)

Problem ist, dass bowtie Eingabe 2 Dateien, ein Index und eine Textdatei nimmt, und ich kann nicht beide von ihnen dem stdin Parameter zuweisen.

Ich habe auch versucht, den Pfad zum Index in den Argumenten aufzunehmen, aber natürlich erkennt Bowtie es nicht als Index und gibt mir einen Fehler. Da dieser Index immer derselbe ist, gibt es eine Möglichkeit, dieses Problem zu vermeiden?

Hier ist ein Teil des Codes i auf (sehr roh) gerade arbeite:

inpath = "/media/2tbhd/workdata/nanocage_noadapt/zf/fasta/zf_ad_c_r2.fasta" 
ind_path = "indexes/zf_gen_topl" 
for elem in plist: 
     cmd = subprocess.call(["bowtie","-f","-v 3", "--best" "--suppress 6,7" "-p 6"], shell = True, stdin = inpath, ind_path) 
+0

Wie würden Sie 'bowtie' von der Befehlszeile aufrufen? Du kannst in keiner mir bekannten Programmiersprache zwei Dateien stdin zuweisen ... – mgilson

+1

"aber natürlich erkennt bowtie es nicht als Index und gibt mir einen Fehler" - welche Fehlermeldung gibt es konkret? –

+0

Bitte versuchen Sie, einen einfachen Shell-Befehl zu schreiben, der bowtie aufruft, wie Sie es wollen, und sehen Sie, ob es funktioniert. Wenn es funktioniert, fügen Sie es hier ein und es wird Ihnen leichter helfen, wie es in eine subprocess.call-Funktion umgewandelt wird. Wenn es nicht funktioniert, kann ich versuchen herauszufinden, was du falsch mit Fliege gemacht hast. – weronika

Antwort

0

Ich weiß nichts über bowtie, aber es scheint mir, dass Ihr Anruf etwas sein sollte wie:

In der Regel übergeben Sie die Liste der Argumente an den Subprozess genau so, wie Sie sie in der Befehlszeile haben würden. Wenn Sie wissen, wie die Befehlszeile aussehen würde, können Sie das wunderbare Modul shlex verwenden, um den Befehl zu teilen. zB:

import shlex 
import subprocess 
cmd=subprocess.call(shlex.split("ls -al")) 
0

Wenn Ihre Eingabedatei tatsächlich eine Datei (das ist, was es wie in Ihrem Beispiel aussieht), nicht verrohrt Daten von einem anderen Prozess, ich glaube nicht, dass Sie STDIN in Ihrem subprocess verwenden sollten .call Funktion überhaupt!
Und soweit ich weiß, können Sie den Index über STDIN nicht zur normalen Befehlszeile liefern - es muss eine Datei sein. Das muss definitiv ein normales Argument sein, nicht von STDIN.

Dies ist, wie ich normalerweise Bowtie aus einem Skript aufrufen (sowohl mit der Eingabedatei und dem Index als Dateien, verwendet keine STDIN):

subprocess.call(["bowtie %s %s %s %s"(full_options,indexname,infile,outfile)], 
       shell=True) 

Wo full_options ist so etwas wie '-f -m1 -v1 --best --tryhard -S --sam-nosq' und indexname so etwas wie 'Chlre4nm_cassette_new_m' ist (Dies ist der Basisname einer Reihe von Indexdateinamen der Form Chlre4nm_cassette_new_m. *. ebwt, in dem Verzeichnis, das durch die Shell-Umgebungsvariable $BOWTIE_INDEXES angegeben wird, und so erkennt bowtie seine Indexdateien).

Ich weiß, ich benutze subprocess.call wahrscheinlich schlecht und sollte mein Kommando/Optionen/Argumente in eine Liste wie in der anderen Antwort teilen - das ist alter Code, aber es funktioniert.

+0

Die Art, wie du das nennst (glaube ich), dass du "bowtie% s ..." nicht in eine Liste schreiben musst ... Ich denke subprocess.call akzeptiert eine Zeichenkette. Der Vorteil der Aufteilung der Zeichenfolge in eine Liste besteht darin, dass Sie die Abhängigkeit von der Shell entfernen können, die effizienter sein sollte und weniger anfällig für Angriffe durch böswillige Benutzer ist ...Wenn das Skript, wenn für Ihren Zweck, (und Sie sind nicht bösartig;), und die Leistung ist kein Problem, dann was Sie haben, ist meiner Meinung nach völlig akzeptabel ... – mgilson

+0

@mgilson - gut zu wissen, danke! Ich weiß, dass das funktioniert (es ist Code, den ich tatsächlich verwende), aber ich wusste nicht, ob es einen Grund gab, ihn in eine Liste aufzuteilen. Eine Frage: Was genau bedeutet "die Abhängigkeit von der Shell entfernen"? Ich frage, weil ich nicht sicher bin, dass es für bowtie möglich ist, da es eine $ BOWTIE_INDEXES-Shellvariable benötigt, um seine Indexdateien zu finden - würde es immer noch funktionieren, wenn ich shell = False setze? – weronika

+0

Ich hatte den Eindruck, dass Subprozess tatsächlich eine neue Shell (/ bin/sh) erzeugt, um den Befehl auszuführen, aber die Dokumentation ist in diesem Punkt eigentlich vage ... Es sagt jedoch, dass es das Äquivalent von launching a ist new shell ... Wenn die Shell-Variable in der Umgebung gesetzt ist, sollte dies in jedem Fall von Python und von jedem von python erzeugten Unterprozess geerbt werden (es sei denn, Sie verwenden das env-Schlüsselwort ...) http: //docs.python .org/library/subprozess.html # popen-konstruktor – mgilson