Frage

    

Diese Frage bereits eine Antwort hier:

         

Wie kann ich die Ausgabe eines Prozessdurchlauf mit subprocess.call() bekommen?

ein StringIO.StringIO Objekt stdout Passing gibt diesen Fehler:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 444, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 588, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 945, in _get_handles
    c2pwrite = stdout.fileno()
AttributeError: StringIO instance has no attribute 'fileno'
>>> 
War es hilfreich?

Lösung

Die Ausgabe von subprocess.call() sollte nur auf Dateien umgeleitet werden.

Sie sollten subprocess.Popen() stattdessen verwenden. Dann können Sie subprocess.PIPE für die stderr, stdout passieren und / oder stdin Parameter und lesen aus den Rohren durch die communicate() Methode:

from subprocess import Popen, PIPE

p = Popen(['program', 'arg1'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
output, err = p.communicate(b"input data that is passed to subprocess' stdin")
rc = p.returncode

Die Begründung ist, dass die Datei-ähnliche Objekt von subprocess.call() verwendet wird, muss eine echte Dateideskriptors hat und somit die fileno() Methode zu implementieren. Verwendung nur eine beliebige Datei-ähnliches Objekt wird nicht den Trick.

Siehe hier für weitere Informationen.

Andere Tipps

Wenn Sie Python-Version> = 2.7, können Sie subprocess.check_output , die genau im Grunde tut, was Sie wollen (es Standardausgabe als String zurückgibt).

Einfaches Beispiel (Linux-Version, siehe Anmerkung):

import subprocess

print subprocess.check_output(["ping", "-c", "1", "8.8.8.8"])

Beachten Sie, dass der Ping-Befehl Linux-Notation verwendet (-c für count). Wenn Sie dies unter Windows versuchen, erinnern sie für gleiches Ergebnis zu -n ändern.

Wie weiter unten Sie kommentiert eine ausführlichere Erklärung in dieser anderen Antwort finden.

ich die folgende Lösung. Es fängt den Exit-Code, die stdout und die stderr zu dem ausgeführten externen Befehl:

import shlex
from subprocess import Popen, PIPE

def get_exitcode_stdout_stderr(cmd):
    """
    Execute the external command and get its exitcode, stdout and stderr.
    """
    args = shlex.split(cmd)

    proc = Popen(args, stdout=PIPE, stderr=PIPE)
    out, err = proc.communicate()
    exitcode = proc.returncode
    #
    return exitcode, out, err

cmd = "..."  # arbitrary external command, e.g. "python mytest.py"
exitcode, out, err = get_exitcode_stdout_stderr(cmd)

Ich habe auch eine Blog-Post auf das hier .

Edit: wurde die Lösung auf eine neuere Version aktualisiert, die nicht auf Temperatur zu schreiben muss. Dateien.

Für Python 3.5 oder höher wird empfohlen, dass Sie die Lauffunktion aus der Verwendung Subprozess Modul . Dies gibt ein CompletedProcess Objekt, von dem Sie bequem die Ausgabe sowie Rückkehrcode erhalten können.

from subprocess import PIPE, run

command = ['echo', 'hello']
result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
print(result.returncode, result.stdout, result.stderr)

Ich dachte nur vor kurzem, wie dies zu tun, und hier einige Beispiel-Code aus einem aktuellen Projekt von mir:

#Getting the random picture.
#First find all pictures:
import shlex, subprocess
cmd = 'find ../Pictures/ -regex ".*\(JPG\|NEF\|jpg\)" '
#cmd = raw_input("shell:")
args = shlex.split(cmd)
output,error = subprocess.Popen(args,stdout = subprocess.PIPE, stderr= subprocess.PIPE).communicate()
#Another way to get output
#output = subprocess.Popen(args,stdout = subprocess.PIPE).stdout
ber = raw_input("search complete, display results?")
print output
#... and on to the selection process ...

Sie haben nun die Ausgabe des Befehls in der Variablen „Ausgang“ gespeichert. „Stdout = subprocess.PIPE“ erzählt die Klasse ein Dateiobjekt namens ‚stdout‘ aus Popen zu erstellen. Die Kommunikation () -Methode, von dem, was ich sagen kann, verhält sich als eine bequeme Art und Weise ein Tupel der den Ausgang und die Fehler aus dem Prozess, den Sie ausgeführt haben zurückzukehren. Auch der Prozess wird ausgeführt, wenn die Instanziierung Popen.

In Ipython Shell:

In [8]: import subprocess
In [9]: s=subprocess.check_output(["echo", "Hello World!"])
In [10]: s
Out[10]: 'Hello World!\n'

Basierend auf Sargue Antwort. Kredit Sargue.

Die folgenden Aufnahmen stdout und stderr des Prozesses in einer einzigen Variablen. Es ist Python 2 und 3 kompatibel:

from subprocess import check_output, CalledProcessError, STDOUT

command = ["ls", "-l"]
try:
    output = check_output(command, stderr=STDOUT).decode()
    success = True 
except CalledProcessError as e:
    output = e.output.decode()
    success = False

Wenn Ihr Befehl ist eine Zeichenfolge, anstatt ein Array, Präfix dies mit:

import shlex
command = shlex.split(command)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top