subproceso: argumento de palabra clave inesperado capture_output

2 minutos de lectura

Al ejecutar subprocess.run() como se da en el Documentos de Pythonobtengo un TypeError:

>>> import subprocess
>>> subprocess.run(["ls", "-l", "/dev/null"], capture_output=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/subprocess.py", line 403, in run
    with Popen(*popenargs, **kwargs) as process:
TypeError: __init__() got an unexpected keyword argument 'capture_output'

Estoy ejecutando Python 3.6.6:

$ python3 --version
Python 3.6.6

  • capture_output es nuevo en Python 3.7.

    –Warren Weckesser

    8 de noviembre de 2018 a las 13:53

avatar de usuario
willem van onsem

Inspeccionó la documentación incorrecta, para python-3.6 este parámetro no no existen, como se puede encontrar en el documentación (usted selecciona la versión en la parte superior izquierda):

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None,
               shell=False, cwd=None, timeout=None, check=False, encoding=None,
               errors=None, env=None)

Sin embargo, puede “emular” esto fácilmente configurando ambos stdout y stderr a PIPE:

from subprocess import PIPE

subprocess.run(["ls", "-l", "/dev/null"], stdout=PIPE, stderr=PIPE)

De hecho, si miramos el código fuente de la versión python-3.7, donde se introdujo la característica, vemos en el código fuente [GitHub]:

if capture_output:
    if ('stdout' in kwargs) or ('stderr' in kwargs):
        raise ValueError('stdout and stderr arguments may not be used '
                         'with capture_output.')
    kwargs['stdout'] = PIPE
    kwargs['stderr'] = PIPE

  • Obtengo “el nombre ‘PIPE’ no está definido” si trato de usar la solución provista aquí.

    – Scorb

    19 de febrero de 2020 a las 1:34

  • @ScottF: lo importaste from subprocess import PIPE (como puede ver en la parte superior del fragmento de código)?

    – Willem Van Onsem

    19 de febrero de 2020 a las 6:42

  • también podrías usar stdout=subprocess.PIPE al mismo efecto sin la importación

    – Rufus VS

    14/07/2021 a las 23:50

El método más simple es usar el subproceso.check_output función:

import subprocess
subprocess.check_output(["ls", "-l", "/dev/null"])

Me encontré con este error porque estaba llamando subprocess.call (que es la antigua API de alto nivel) en lugar de subprocess.run.

¿Ha sido útil esta solución?