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.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
python
subprocess
popen
imaginateur
la source
la source
echo hi
imprimehi\r\n
. Pour éviter cela, vous pouvez ajouter .strip () à la fin, ou un correctif similaire.check_output()
place d'.communicate()
ici:print(subprocess.check_output("echo hi", shell=True, universal_newlines=True), end="")
Réponses:
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 qui équivaut à une chaîne normale en Python 2.6+
http://docs.python.org/3/reference/lexical_analysis.html#literals
la source
Le
b
indique que ce que vous avez estbytes
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 quicommunicate()
revient.Le
bytes
type n'est pas directementprint()
capable, donc on vous montre lerepr
quebytes
vous avez. Si vous connaissez le codage des octets que vous avez reçus du sous-processus, vous pouvez utiliserdecode()
pour les convertir en un imprimablestr
:>>> print(b'hi\n'.decode('ascii')) hi
Bien sûr, cet exemple spécifique ne fonctionne que si vous recevez réellement l'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 qui
echo hi
a une sortie.echo
Le travail de ce dernier est de sortir les paramètres que vous lui transmettez, suivis d 'une nouvelle ligne. Si vous n'êtes pas intéressé par les espaces autour de la sortie du processus, vous pouvez utiliserstrip()
comme ceci:>>> b'hi\n'.strip() b'hi'
la source
os.popen
renvoie des chaînes de texte, s'il existe un moyen de les rendresubprocess.Popen
également, au lieu des chaînes d'octets.universal_newlines
qui fait que l'Popen
objet accepte et renvoie des chaînes de texte.check_output("dir")
, l'extraction d'un nom de fichier de la sortie puis la tentative d'accès avecopen
échouera si le nom de fichier contient des trémas allemands. Ça pourrait être un bug.Comme mentionné précédemment,
echo hi
renvoie effectivementhi\n
, ce qui est un comportement attendu.Mais vous voulez probablement simplement obtenir les données dans un «bon» format et ne pas vous occuper du codage. Tout ce que vous avez à faire est de passer l'
universal_newlines=True
option poursubprocess.Popen()
aimer ainsi:>>> import subprocess >>> print(subprocess.Popen("echo hi", shell=True, stdout=subprocess.PIPE, universal_newlines=True).communicate()[0]) hi
De cette manière
Popen()
, ces symboles indésirables seront remplacés par eux-mêmes.la source
universal_newlines=True
a fonctionné comme un charme. Cela devrait être la réponse acceptée, à mon humble avis ...universal_newlines=True
inPopen
(pour vous débarrasser deb''
) et astrip()
sur la chaîne résultante, si vous souhaitez couper la nouvelle ligne de fin.universal_newlines
s'agit maintenant que d'un alias rétrocompatible pour letext
paramètre, ce qui est plus clair mais uniquement en Python 3.7 et supérieur.b est la représentation en octets et \ n est le résultat de la sortie d'écho.
Ce qui suit n'imprimera que les données de résultat
import subprocess print(subprocess.Popen("echo hi", shell=True,stdout=subprocess.PIPE).communicate()[0].decode('utf-8').strip())
la source