Salida de subproceso.Popen

He estado escribiendo un código de Python y en mi código estaba usando “comando”

El código estaba funcionando como lo esperaba pero luego noté en los documentos de Python que el comando ha quedado en desuso y se eliminará en Python 3 y que debería usar “subproceso” en su lugar.

“OK”, creo, “no quiero que mi código vaya directamente al estado heredado, por lo que debería cambiarlo ahora mismo.

La cosa es que subprocess.Popen parece anteponer una cadena desagradable al inicio de cualquier salida, por ejemplo

 

Todos los ejemplos que veo lo tienen allí, parece que se acepta dado que siempre está ahí.

Este codigo

 #!/usr/bin/python import subprocess output = subprocess.Popen("ls -al", shell=True) print output 

produce esto

  brettg@underworld:~/dev$ total 52 drwxr-xr-x 3 brettg brettg 4096 2011-05-27 12:38 . drwxr-xr-x 21 brettg brettg 4096 2011-05-24 17:40 ..  

¿Esto es normal? Si lo uso como parte de un progtwig más grande que envía varios detalles formateados a la consola, desordena todo.

Estoy usando el comando para obtener la dirección IP para una interfaz usando ifconfig junto con varios greps y awks para raspar la dirección.

Considere este código;

 #!/usr/bin/python import commands,subprocess def new_get_ip (netif): address = subprocess.Popen("/sbin/ifconfig " + netif + " | grep inet | grep -v inet6 | awk '{print $2}' | sed 's/addr://'i", shell=True) return address def old_get_ip (netif): address = commands.getoutput("/sbin/ifconfig " + netif + " | grep inet | grep -v inet6 | awk '{print $2}' | sed 's/addr://'i") return address print "OLD IP is :",old_get_ip("eth0") print "" print "NEW IP is :",new_get_ip("eth0") 

Esto vuelve;

 brettg@underworld:~/dev$ ./IPAddress.py OLD IP is : 10.48.16.60 NEW IP is :  brettg@underworld:~/dev$ 10.48.16.60 

Lo que es feo por decir lo menos.

Obviamente me falta algo aquí. Soy nuevo en Python, por supuesto, así que estoy seguro de que estoy haciendo lo incorrecto, pero varias búsquedas de google han sido infructuosas hasta este momento.

¿Qué pasa si quiero una salida más limpia? ¿Tengo que recortar manualmente la salida ofensiva o estoy invocando subprocess.Popen de forma incorrecta?

¡Gracias por adelantado!

La “cadena fea” es lo que debería estar imprimiendo. Python está imprimiendo correctamente la repr(subprocess.Popen(...)) , tal como lo imprimiría si dijera print(open('myfile.txt')) .

Además, Python no tiene conocimiento de lo que se está enviando a la salida estándar. La salida que está viendo no es de python, sino de que stdout y stderr del proceso se redirigen a su terminal como spam, que ni siquiera está pasando por el proceso de python. Es como si ejecutara un progtwig en someprogram & progtwig someprogram & sin redirigir su stdout y stderr a /dev/null , y luego intentó ejecutar otro comando, pero ocasionalmente vería spam desde el progtwig. Para repetir y aclarar:

  <-- output of python program brettg@underworld:~/dev$ total 52 <-- spam from your shell, not from python drwxr-xr-x 3 brettg brettg 4096 2011-05-27 12:38 . <-- spam from your shell, not from python drwxr-xr-x 21 brettg brettg 4096 2011-05-24 17:40 .. <-- spam from your shell, not from python ... 

Para capturar la .communicate() , debe usar la función .communicate() , así:

 #!/usr/bin/python import subprocess output = subprocess.Popen(["ls", "-a", "-l"], stdout=subprocess.PIPE).communicate()[0] print output 

Además, nunca querrá usar shell=True , ya que es un agujero de seguridad (un agujero de seguridad importante con entradas no saneadas, una de menor importancia sin entrada porque permite ataques locales modificando el entorno de la shell). Por razones de seguridad y también para evitar errores, generalmente desea pasar una lista en lugar de una cadena. Si eres perezoso, puedes hacer "ls -al" .split (), que no está bien visto, pero sería un agujero de seguridad hacer algo como ("ls -l% s"% unsanitizedInput) .split ().