Python: ¿Cómo obtener stdout después de ejecutar os.system?
python-2.7 stderr (4)
Estas respuestas no funcionaron para mí. Tuve que usar lo siguiente:
import subprocess
p = subprocess.Popen(["pwd"], stdout=subprocess.PIPE)
out = p.stdout.read()
print out
O como una función (usar Shell = True fue requerido para mí en Python 2.6.7 y check_output no se agregó hasta 2.7, por lo que es inutilizable aquí):
def system_call(command):
p = subprocess.Popen([command], stdout=subprocess.PIPE, shell=True)
return p.stdout.read()
Quiero obtener el stdout
en una variable después de ejecutar la llamada al sistema os.system
.
Tomemos esta línea como ejemplo:
batcmd="dir"
result = os.system(batcmd)
result
contendrá el código de error ( stderr
0
en Windows o 1
en algunos linux para el ejemplo anterior).
¿Cómo puedo obtener el stdout
para el comando anterior sin usar la redirección en el comando ejecutado?
Me gustaría ampliar la solución de Windows. Usando IDLE con Python 2.7.5, cuando ejecuto este código desde el archivo Expts.py:
import subprocess
r = subprocess.check_output(''cmd.exe dir'',shell=False)
print r
... en Python Shell, SÓLO obtengo el resultado correspondiente a "cmd.exe"; la parte "dir" se ignora. SIN EMBARGO, cuando agrego un interruptor como / K o / C ...
import subprocess
r = subprocess.check_output(''cmd.exe /K dir'',shell=False)
print r
... luego en Python Shell, obtengo todo lo que espero, incluida la lista de directorios. Woohoo!
Ahora, si pruebo cualquiera de esas mismas cosas en la ventana de comandos de Python de DOS, sin el interruptor, o con el modificador / K, parece que la ventana se cuelga porque está ejecutando un subproceso cmd.exe y esperando más entradas - tipo ''salir'' luego presionar [enter] para liberar. Pero con el modificador / K funciona perfectamente y lo devuelve al indicador de Python. Allrightee entonces.
Fui un paso más allá ... Pensé que esto era genial ... cuando en cambio hago esto en Expts.py:
import subprocess
r = subprocess.call("cmd.exe dir",shell=False)
print r
... una nueva ventana de DOS se abre y permanece allí mostrando solo los resultados de "cmd.exe" no de "dir". Cuando agrego el modificador / C, la ventana de DOS se abre y cierra muy rápido antes de que pueda ver algo (como se esperaba, porque / C termina cuando termina). Cuando en su lugar agrego el modificador / K, la ventana de DOS se abre y permanece, Y obtengo todos los resultados que espero, incluida la lista del directorio.
Si intento lo mismo (subprocess.call en lugar de subprocess.check_output) desde una ventana de comandos Python de DOS; todos los resultados están dentro de la misma ventana, no hay ventanas emergentes. Sin el interruptor, nuevamente se ignora la parte "dir" Y el aviso cambia del indicador de Python al indicador de DOS (dado que un subproceso cmd.exe se está ejecutando en python; de nuevo escriba ''exit'' y volverá al indicador de Python ) Al agregar el modificador / K, se imprime la lista del directorio y se cambia la solicitud de pitón a DOS, ya que / K no finaliza el subproceso. Cambiar el interruptor a / C nos da toda la salida esperada Y retorna al indicador de Python dado que el subproceso termina de acuerdo con / C.
Perdón por la respuesta larga, pero estoy frustrado en este foro con las muchas ''respuestas'' escuetas que en el mejor de los casos no funcionan (parece que no están probadas, como la respuesta de Eduard F sobre la mía que falta el interruptor) o peor, son tan escuetos que no ayudan mucho en absoluto (p. ej., ''prueba el subproceso en lugar de os.system'' ... sí, está bien, ¿y ahora qué?). Por el contrario, proporcioné soluciones que probé y mostré cómo hay diferencias sutiles entre ellas. Tomó mucho tiempo pero ... Espero que esto ayude.
Si todo lo que necesita es la salida stdout
, eche un vistazo a subprocess.check_output()
(agregado en Python 2.7):
import subprocess
batcmd="dir"
result = subprocess.check_output(batcmd, shell=True)
Como usaba os.system()
, tendría que establecer shell=True
para obtener el mismo comportamiento. Desea escuchar el gran mensaje de advertencia rojo sobre pasar argumentos no confiables a su shell.
Si necesita capturar stderr
también, simplemente agregue stderr=subprocess.STDOUT
a la llamada:
result = subprocess.check_output([batcmd], stderr=subprocess.STDOUT)
para redirigir la salida de error a la secuencia de salida predeterminada.
commands
también funciona.
import commands
batcmd = "dir"
result = commands.getoutput(batcmd)
print result
Funciona en Linux, Python 2.7.