python - Salida estándar del subproceso de tubería a una variable
subprocess pipe (3)
Con a = subprocess.Popen("cdrecord --help",stdout = subprocess.PIPE)
, necesita usar una lista o usar shell=True
;
Cualquiera de estos funcionará. El primero es preferible.
a = subprocess.Popen([''cdrecord'', ''--help''], stdout=subprocess.PIPE)
a = subprocess.Popen(''cdrecord --help'', shell=True, stdout=subprocess.PIPE)
Además, en lugar de usar Popen.stdout.read
/ Popen.stderr.read
, debe usar .communicate()
(consulte la documentación del subproceso para .communicate()
por qué).
proc = subprocess.Popen([''cdrecord'', ''--help''], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
Quiero ejecutar un comando en pythong
, usando el módulo de subproceso, y almacenar el resultado en una variable. Sin embargo, no quiero que la salida del comando se imprima en el terminal. Para este código:
def storels():
a = subprocess.Popen("ls",shell=True)
storels()
Obtengo el listado del directorio en la terminal, en lugar de tenerlo almacenado en a
. También lo intenté:
def storels():
subprocess.Popen("ls > tmp",shell=True)
a = open("./tmp")
[Rest of Code]
storels()
Esto también imprime la salida de ls a mi terminal. Incluso he intentado este comando con el método del sistema os. algo anticuado, ya que ejecutar ls > tmp
en el terminal no imprime ls
en absoluto en el terminal, sino que lo almacena en tmp
. Sin embargo, pasa lo mismo.
Editar:
Recibo el siguiente error después de seguir el consejo de marcog, pero solo cuando ejecuto un comando más complejo. cdrecord --help
Python escupe esto:
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
Para obtener la salida de ls
, use stdout=subprocess.PIPE
.
>>> proc = subprocess.Popen(''ls'', stdout=subprocess.PIPE)
>>> output = proc.stdout.read()
>>> print output
bar
baz
foo
El comando cdrecord --help
saca a stderr, por lo que debe canalizar ese indstead. También deberías dividir el comando en una lista de tokens como he hecho a continuación, o la alternativa es pasar el argumento shell=True
pero esto dispara un caparazón completamente desarrollado que puede ser peligroso si no controlas el comando. contenido de la cadena de comando.
>>> 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 #.
...
Si tiene un comando que genera tanto stdout como stderr y desea fusionarlos, puede hacerlo conectando stderr a stdout y luego capturando stdout.
subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
Como menciona Chris Morgan , debería usar proc.communicate()
lugar de 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 #.
...
Si está utilizando Python 2.7 o posterior, la forma más fácil de hacerlo es usar el comando subprocess.check_output()
. Aquí hay un ejemplo:
output = subprocess.check_output(''ls'')
Para redirigir también stderr, puede usar lo siguiente:
output = subprocess.check_output(''ls'', stderr=subprocess.STDOUT)
En el caso de que desee pasar parámetros al comando, puede usar una lista o usar invocar un shell y usar una sola cadena.
output = subprocess.check_output([''ls'', ''-a''])
output = subprocess.check_output(''ls -a'', shell=True)