web-dev-qa-db-fra.com

Pourquoi Popen.communicate () renvoie b'hi \ n 'au lieu de' hi '?

Quelqu'un peut-il expliquer pourquoi le résultat que je veux, "salut", est précédé d'une lettre "b" et suivi d'une nouvelle ligne?

J'utilise Python 3.

>>> import subprocess
>>> print(subprocess.Popen("echo hi", Shell=True,
                           stdout=subprocess.PIPE).communicate()[0])
b'hi\n'

Ce "b" supplémentaire n'apparaît pas si je l'exécute avec python 2.7

55
imagineerThat

La commande echo renvoie par défaut un caractère de nouvelle ligne

Comparez avec ceci:

print(subprocess.Popen("echo -n hi", \
    Shell=True, stdout=subprocess.PIPE).communicate()[0])

Quant au b précédant la chaîne, il indique qu'il s'agit d'une séquence d'octets équivalente à une chaîne normale dans Python = 2,6+

http://docs.python.org/3/reference/lexical_analysis.html#literals

10
Necrolyte2

b indique que ce que vous avez est bytes , qui est une séquence binaire d'octets plutôt qu'une chaîne de caractères Unicode. Les sous-processus produisent des octets, pas des caractères, c'est donc ce que communicate() retourne.

Le type bytes n'est pas directement print() capable, donc on vous montre le repr du bytes que vous avez. Si vous connaissez l'encodage des octets que vous avez reçus du sous-processus, vous pouvez utiliser decode() pour les convertir en str imprimable:

>>> print(b'hi\n'.decode('ascii'))
hi

Bien sûr, cet exemple spécifique ne fonctionne que si vous recevez réellement ASCII du sous-processus. Si ce n'est pas ASCII, vous obtiendrez une exception:

>>> 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 nouvelle ligne fait partie de ce que echo hi A produit. Le travail de echo consiste à sortir les paramètres que vous lui transmettez, suivi d'une nouvelle ligne. Si vous n'êtes pas intéressé par les espaces autour de la sortie du processus, vous pouvez utiliser strip() comme ceci:

>>> b'hi\n'.strip()
b'hi'
71
zigg

Comme mentionné précédemment, echo hi Renvoie en fait hi\n, Ce qui est un comportement attendu.

Mais vous voulez probablement simplement obtenir les données dans un "bon" format et ne pas traiter l'encodage. Tout ce que vous devez faire est de passer l'option universal_newlines=True À subprocess.Popen() comme ceci:

>>> import subprocess
>>> print(subprocess.Popen("echo hi",
                           Shell=True,
                           stdout=subprocess.PIPE,
                           universal_newlines=True).communicate()[0])
hi

De cette façon, Popen() remplacera ces symboles indésirables par lui-même.

26
Danil

b est la représentation des octets et\n est le résultat de la sortie d'écho.

Ce qui suit imprime uniquement les données de résultat

import subprocess
print(subprocess.Popen("echo hi", Shell=True,stdout=subprocess.PIPE).communicate()[0].decode('utf-8').strip())
7
Jenish