2016-05-14 11 views
0

Ich arbeite an etwas wie kompilieren, und ich versuche, Assembler zu kompilieren und die Ausgabeinformationen über es mit subprocess.Subprozess getoutput funktioniert nicht

Als ich subprocess.call alles funktioniert gut, wie bin mit:

(ich einige Spam, um es hinzuzufügen, so wird es Ausgabe ein Fehler)

Version : Python3.5 

In [12]: subprocess.call(['as','-32','test.s']) 
test.s: Assembler messages: 
test.s:3: Error: no such instruction: `zxvasdf' 
Out[12]: 1 

Aber wenn ich subprocess.getoutput:

In [13]: subprocess.getoutput(['as','-32','test.s']) 

Es einfach einfrieren und nichts tun.

Wie kann ich dieses Problem lösen?

Vielen Dank für jeden Hinweis.

Antwort

2

Die Frage, wie @Lex Scarisbrick correctly noticed ist, dass getoutput(cmd) einen Shell-Befehl als Zeichenfolge erwartet. Wenn Sie eine Liste übergeben; Die zusätzlichen Argumente werden in POSIX an die Shell übergeben, nicht an den Prozess 'as'. Das bedeutet, dass das Programm 'as' ohne Befehlszeilenargumente ausgeführt wird.

Es einfach einfrieren und nichts tun.

Es scheint as aufgerufen ohne Befehlsargumente wartet auf seine Eingabe auf Stdin. Sie können beginnen, etwas Assembler einzugeben und Ctrl+D drücken, um EOF anzuzeigen. Wenn Sie keine Eingabe bereitstellen; es wird für immer hängen bleiben.

Siehe Why subprocess.Popen doesn't work when args is sequence?

Wenn Sie sowohl stdout, stderr von 'as' subprocess lesen wollen; Sie könnten subprocess.run() verwenden:

#!/usr/bin/env python3 
import subprocess 

p = subprocess.run(['as','-32','test.s'], 
        stdout=subprocess.PIPE, 
        stderr=subprocess.PIPE, # capture separately 
        universal_newline=True) # decode bytes 
print("Status: {p.returncode}, stdout: {p.stdout}, stderr: {p.stderr}".format(p=p)) 

Hinweis: Sie shell=True hier nicht verwenden.

0

Nun, es scheint, ich kann subprocess.PIPE verwenden, um das Problem zu lösen.

In [16]: proc = subprocess.Popen(['as','-32','test.s'],stdout=subprocess.PIPE,stderr=subprocess.PIPE) 

In [17]: for i in proc.stderr: 
    ....:  print(i) 
    ....:  
b'test.s: Assembler messages:\n' 
b"test.s:3: Error: no such instruction: `zxvasdf'\n" 

Aber ich verstehe nicht ganz, warum ich gut geht.

Ich werde das Dokument für weitere Details überprüfen.

Danke für alle.

+0

PIPE nicht übergeben, es sei denn, Sie lesen aus der Pipe, während der Prozess noch läuft, andernfalls kann ein Deadlock auftreten. – jfs

0

subprocess.getouput() nimmt keine Liste als Eingabe wie subprocess.call() tut. Es braucht ein einzelnes Argument als String. Ändern Sie ihn auf:

subprocess.getoutput('as -32 test.s') 
+0

sollten Sie versuchen, 'subprocess.getoutput (['ls', '- a'])' – KIDJourney

+0

Es dauert nur das erste Argument. 'getoutput ('ls -a')' liefert eine andere Ausgabe als 'getoutput ([' ls ',' - a ']) ''. Da nur das erste Argument verwendet wird, hängt der 'as'-Befehl in der obigen Frage und wartet auf die Eingabe. –

+0

args ist für alle Aufrufe erforderlich und sollte eine Zeichenfolge oder eine Sequenz von Programmargumenten sein. Die Bereitstellung einer Folge von Argumenten wird im Allgemeinen bevorzugt, da es dem Modul erlaubt, sich um das erforderliche Entweichen und Zitieren von Argumenten zu kümmern (z. B. um Leerzeichen in Dateinamen zuzulassen). Wenn eine einzelne Zeichenkette übergeben wird, muss jede der beiden Einheiten True sein (siehe unten), oder die Zeichenkette muss einfach das Programm benennen, das ohne Angabe von Argumenten ausgeführt werden soll. – KIDJourney