python Pipe-Subprozess-Standardausgabe an eine Variable



subprocess python-2.6 (3)

Ich möchte einen Befehl in pythong , das pythong verwenden und die Ausgabe in einer Variablen speichern. Ich möchte jedoch nicht, dass die Ausgabe des Befehls auf dem Terminal gedruckt wird. Für diesen Code:

def storels():
   a = subprocess.Popen("ls",shell=True)
storels()

Ich bekomme die Verzeichnisliste im Terminal, anstatt sie in a . Ich habe es auch versucht:

 def storels():
       subprocess.Popen("ls > tmp",shell=True)
       a = open("./tmp")
       [Rest of Code]
 storels()

Dies gibt auch die Ausgabe von ls an mein Terminal aus. Ich habe sogar diesen Befehl mit der etwas veralteten os.system-Methode ausprobiert, da das Ausführen von ls > tmp im Terminal ls an das Terminal ausgibt, sondern in tmp speichert. Das Gleiche passiert jedoch.

Bearbeiten:

Ich erhalte den folgenden Fehler, nachdem ich dem Rat von Marcog gefolgt bin, aber nur wenn ich einen komplexeren Befehl ausführe. cdrecord --help . Python spuckt das aus:

Traceback (most recent call last):
  File "./install.py", line 52, in <module>
    burntrack2("hi")
  File "./install.py", line 46, in burntrack2
    a = subprocess.Popen("cdrecord --help",stdout = subprocess.PIPE)
  File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
    errread, errwrite)
  File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

Wenn Sie Python 2.7 oder höher verwenden, können Sie dies am einfachsten mit dem Befehl subprocess.check_output() tun. Hier ist ein Beispiel:

output = subprocess.check_output('ls')

Um auch stderr umzuleiten, können Sie folgendes verwenden:

output = subprocess.check_output('ls', stderr=subprocess.STDOUT)



Für den Fall, dass Sie Parameter an den Befehl übergeben möchten, können Sie entweder eine Liste verwenden oder eine Shell aufrufen und eine einzelne Zeichenfolge verwenden.

output = subprocess.check_output(['ls', '-a'])
output = subprocess.check_output('ls -a', shell=True)

Um die Ausgabe von ls , verwenden Sie stdout=subprocess.PIPE .

>>> proc = subprocess.Popen('ls', stdout=subprocess.PIPE)
>>> output = proc.stdout.read()
>>> print output
bar
baz
foo

Der Befehl cdrecord --help gibt die cdrecord --help an stderr aus. Sie sollten den Befehl auch in eine Liste von Tokens aufteilen, wie ich es unten getan habe, oder die Alternative besteht darin, das shell=True Argument zu übergeben, aber dies erzeugt eine ausgewachsene Shell, die gefährlich sein kann, wenn Sie das nicht kontrollieren Inhalt der Befehlszeichenfolge.

>>> proc = subprocess.Popen(['cdrecord', '--help'], stderr=subprocess.PIPE)
>>> output = proc.stderr.read()
>>> print output
Usage: wodim [options] track1...trackn
Options:
    -version    print version information and exit
    dev=target  SCSI target to use as CD/DVD-Recorder
    gracetime=# set the grace time before starting to write to #.
...

Wenn Sie einen Befehl haben, der sowohl an stdout als auch an stderr ausgegeben wird und Sie diese zusammenführen möchten, können Sie dies tun, indem Sie stderr in stdout einfügen und dann stdout abfangen.

subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

Wie von Chris Morgan erwähnt , sollten Sie proc.communicate() anstelle von proc.read() .

>>> proc = subprocess.Popen(['cdrecord', '--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> out, err = proc.communicate()
>>> print 'stdout:', out
stdout: 
>>> print 'stderr:', err
stderr:Usage: wodim [options] track1...trackn
Options:
    -version    print version information and exit
    dev=target  SCSI target to use as CD/DVD-Recorder
    gracetime=# set the grace time before starting to write to #.
...

Mit a = subprocess.Popen("cdrecord --help",stdout = subprocess.PIPE) müssen Sie entweder eine Liste verwenden oder shell=True ;

Eines davon wird funktionieren. Ersteres ist vorzuziehen.

a = subprocess.Popen(['cdrecord', '--help'], stdout=subprocess.PIPE)

a = subprocess.Popen('cdrecord --help', shell=True, stdout=subprocess.PIPE)

Anstatt Popen.stdout.read / Popen.stderr.read , sollten Sie auch .communicate() ( Popen.stderr.read Sie in der Subprozessdokumentation nach why).

proc = subprocess.Popen(['cdrecord', '--help'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()




python-2.6