2013-03-12 10 views
30

Kann jemand erklären, warum das gewünschte Ergebnis, "hi", mit einem Buchstaben "b" vorangestellt wird, gefolgt von einem Zeilenumbruch?Warum gibt Popen.communicate() b'hi n 'anstelle von' hi 'zurück?

Ich verwende Python 3,3

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

Diese zusätzliche 'b' erscheint nicht, wenn ich es mit Python laufen 2.7

+0

Welche Version von Python verwenden Sie? – Necrolyte2

+0

Verwenden von Version 3.3 – imagineerThat

+2

Nicht sicher über das 'b', aber die Newline ist, weil 'hallo hallo' 'hi \ r \ n' druckt. Um dies zu vermeiden, könnten Sie am Ende oder einem ähnlichen Fix .strip() hinzufügen. – azhrei

Antwort

4

Der Echo-Befehl standardmäßig ein Newline-Zeichen gibt

Vergleichen Sie dies mit:

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

Was die b die Zeichenfolge vorangehenden es anzeigt, dass es sich um eine Byte-Sequenz ist, die zu einer normalen Zeichenfolge in Python equivilent wird 2.6+

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

+2

you don ' t brauche '\' in den Klammern. – jfs

44

Die b zeigt an, dass, was Sie haben bytes ist, das ist eine binäre Sequenz von Bytes anstelle einer Zeichenfolge von Unicode-Zeichen. Unterprozessausgabebytes, nicht Zeichen, das ist also was communicate() zurückgibt.

Der bytes Typ ist nicht direkt print() der Lage, so dass Sie die repr der bytes gezeigt werden sind Sie haben. Wenn Sie die Codierung der Bytes wissen Sie von der subprocess erhalten haben, können Sie decode() nutzen sie in ein druckbares str zu konvertieren:

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

Natürlich ist dieses spezifische Beispiel funktioniert nur, wenn Sie tatsächlich ASCII aus dem subprocess erhalten . Wenn es nicht ASCII ist, erhalten Sie eine Ausnahme erhalten:

>>> 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… 

Das Newline-Teil ist, was echo hi Ausgang. echo ist der Auftrag, die Parameter, die Sie übergeben, gefolgt von einem Zeilenumbruch auszugeben. Wenn Sie in Leerzeichen rund um den Prozessausgang nicht interessiert sind, können Sie strip() wie so verwenden:

>>> b'hi\n'.strip() 
b'hi' 
+0

Wie erhalten Sie die Funktion print(), um eine Byte-Zeichenfolge ohne vorangestelltes 'b' zu drucken? Oder müssen Sie es zuerst in eine Unicode-Zeichenfolge konvertieren? – imagineerThat

+0

Ja; Siehe meine Bearbeitung. Bedenken Sie aber auch die Gefahren der Entschlüsselung. – zigg

+0

Ich bin gespannt, wenn 'os.popen' Textzeichenfolgen zurückgibt, ob es eine Möglichkeit gibt, 'subprocess.Popen' auch an Stelle der Byte-Zeichenfolgen zurückgeben zu lassen. –

2

b ist die Byte-Darstellung und \ n ist das Ergebnis der Echo ausgegeben.

druckt Nach nur die Ergebnisdaten

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

Wie bereits erwähnt, echo hi tatsächlich hi\n zurückgibt, das es ein erwartetes Verhalten ist.

Aber Sie möchten wahrscheinlich nur die Daten in einem "richtigen" Format und nicht mit Codierung beschäftigen. Alles, was Sie tun müssen, ist, wie so universal_newlines=True Option subprocess.Popen() passieren:

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

Auf diese Weise Popen() wird diese unerwünschten Symbole selbst ersetzen.

Verwandte Themen