Cómo se utiliza el subproceso.¿comprobar output() en Python?


He encontrado documentación sobre subproceso.check_output () pero no puedo encontrar uno con argumentos y la documentación no es muy en profundidad. Estoy usando Python 3 (pero estoy tratando de ejecutar un archivo Python 2 a través de Python 3)

Estoy tratando de ejecutar este comando: python py2.py -i test.txt

-i es un argumento posicional para argparse, test.txt es lo que el - i es, py2.py es el archivo a ejecutar

He intentado un montón de (no funciona) variaciones incluyendo: py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])

py2output = subprocess.check_output([str('python'),'py2.py','-i', test.txt'])

Author: JOHANNES_NYÅTT, 2012-12-29

2 answers

La respuesta correcta (usando Python 2.7 y posterior, ya que check_output() se introdujo entonces ) es:

py2output = subprocess.check_output(['python','py2.py','-i', 'test.txt'])

Para demostrar, aquí están mis dos programas:

Py2.py:

import sys
print sys.argv

Py3.py:

import subprocess
py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'])
print('py2 said:', py2output)

Ejecutándolo:

$ python3 py3.py
py2 said: b"['py2.py', '-i', 'test.txt']\n"

Esto es lo que está mal con cada una de sus versiones:

py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])

Primero, str('python py2.py') es exactamente lo mismo que 'python py2.py'-estás tomando un str, y llamando a str para convertirlo en un str. Esto hace que el código sea más difícil de leer, más largo y aún más lento, sin añadir ningún beneficio.

Más en serio, python py2.py no puede ser un solo argumento, a menos que realmente estés tratando de ejecutar un programa llamado, digamos, /usr/bin/python\ py2.py. Que no lo eres; estás tratando de ejecutar, digamos, /usr/bin/python con el primer argumento py2.py. Por lo tanto, es necesario hacer que los elementos separados en la lista.

Su segunda versión corrige eso, pero le falta el ' antes de test.txt'. Esto debería darte un SyntaxError, probablemente diciendo EOL while scanning string literal.

Mientras tanto, no estoy seguro de cómo se encontró documentación pero no se pudo encontrar ningún ejemplo con argumentos. El primer ejemplo es:

>>> subprocess.check_output(["echo", "Hello World!"])
b'Hello World!\n'

Que llama al comando "echo" con un argumento adicional, "Hello World!".

También:

-i es un argumento posicional para argparse, test.txt es lo que el-i es

Estoy bastante seguro de que -i es no un argumento posicional, sino un argumento opcional. De lo contrario, la segunda mitad de la oración no tiene sentido.

 56
Author: abarnert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-29 20:20:36

Añadiendo al mencionado por @abarnert

Una mejor es atrapar la excepción

import subprocess
try:
    py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'],stderr= subprocess.STDOUT)  
    #print('py2 said:', py2output)
    print "here"
except subprocess.CalledProcessError as e:
    print "Calledprocerr"

Este stderr= subproceso.STDOUT es para asegurarse de que no obtenga el error filenotfound en stderr, que generalmente no puede ser atrapado en filenotfoundexception, de lo contrario, terminaría obteniendo

python: can't open file 'py2.py': [Errno 2] No such file or directory

De hecho, una mejor solución a esto podría ser comprobar si el archivo/scripts existe y luego ejecutar el archivo/script

 2
Author: ravi.zombie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-30 06:17:14