python subprocess pipe python-2.6

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)