¿Alguien puede explicar por qué el resultado que quiero, "hola", está precedido por una letra "b" y seguido de una nueva línea?
Estoy usando Python 3.3
>>> import subprocess
>>> print(subprocess.Popen("echo hi", shell=True,
stdout=subprocess.PIPE).communicate()[0])
b'hi\n'
Esta 'b' adicional no aparece si la ejecuto con Python 2.7
python
subprocess
popen
Imaginador que
fuente
fuente
echo hi
imprimehi\r\n
. Para evitar eso, puede agregar .strip () al final, o una solución similar.check_output()
lugar de.communicate()
aquí:print(subprocess.check_output("echo hi", shell=True, universal_newlines=True), end="")
Respuestas:
El comando echo por defecto devuelve un carácter de nueva línea
Compare con esto:
print(subprocess.Popen("echo -n hi", \ shell=True, stdout=subprocess.PIPE).communicate()[0])
En cuanto a la b que precede a la cadena, indica que es una secuencia de bytes que es equivalente a una cadena normal en Python 2.6+
http://docs.python.org/3/reference/lexical_analysis.html#literals
fuente
El
b
indica que lo que tiene esbytes
, que es una secuencia binaria de bytes en lugar de una cadena de caracteres Unicode. Subprocesa bytes de salida, no caracteres, así que esocommunicate()
es lo que está regresando.El
bytes
tipo no es directamenteprint()
capaz, por lo que se le muestrarepr
elbytes
que tiene. Si conoce la codificación de los bytes que recibió del subproceso, puede usarlosdecode()
para convertirlos en imprimiblesstr
:>>> print(b'hi\n'.decode('ascii')) hi
Por supuesto, este ejemplo específico solo funciona si realmente está recibiendo ASCII del subproceso. Si no es ASCII, obtendrá una excepción:
>>> print(b'\xff'.decode('ascii')) Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0…
La nueva línea es parte de lo que
echo hi
tiene salida.echo
El trabajo es generar los parámetros que le pasas, seguidos de una nueva línea. Si no está interesado en los espacios en blanco que rodean la salida del proceso, puede usarstrip()
así:>>> b'hi\n'.strip() b'hi'
fuente
os.popen
devuelve cadenas de texto, si hay una manera de hacer quesubprocess.Popen
también las devuelva, en lugar de las cadenas de bytes.universal_newlines
que hace que elPopen
objeto acepte y devuelva cadenas de texto.check_output("dir")
, ejecutar , extraer un nombre de archivo de la salida y luego intentar acceder a élopen
fallará si el nombre del archivo contiene diéresis en alemán. Podría ser un error.Como se mencionó anteriormente, en
echo hi
realidad regresahi\n
, lo cual es un comportamiento esperado.Pero probablemente desee obtener los datos en un formato "correcto" y no ocuparse de la codificación. Todo lo que necesitas hacer es pasar la
universal_newlines=True
opción para que tesubprocess.Popen()
guste:>>> import subprocess >>> print(subprocess.Popen("echo hi", shell=True, stdout=subprocess.PIPE, universal_newlines=True).communicate()[0]) hi
De esta manera
Popen()
reemplazará estos símbolos no deseados por sí solo.fuente
universal_newlines=True
trabajado como un encanto. Esta debería ser la respuesta aceptada, en mi humilde opinión ...universal_newlines=True
inPopen
(para deshacerse deb''
) como astrip()
en la cadena resultante, si desea cortar la nueva línea de terminación.universal_newlines
que ahora es solo un alias compatible con versiones anteriores para eltext
parámetro, que es más claro pero solo en Python 3.7 y superior.b es la representación de bytes y \ n es el resultado de la salida de eco.
Lo siguiente imprimirá solo los datos del resultado
import subprocess print(subprocess.Popen("echo hi", shell=True,stdout=subprocess.PIPE).communicate()[0].decode('utf-8').strip())
fuente