Czy ktoś może wyjaśnić, dlaczego oczekiwany przeze mnie wynik, „cześć”, jest poprzedzony literą „b” i zakończony nową linią?
Używam Pythona 3.3
>>> import subprocess
>>> print(subprocess.Popen("echo hi", shell=True,
stdout=subprocess.PIPE).communicate()[0])
b'hi\n'
To dodatkowe `` b '' nie pojawia się, jeśli uruchomię go z Pythonem 2.7
python
subprocess
popen
imagineerThat
źródło
źródło
echo hi
drukowanyhi\r\n
. Aby tego uniknąć, możesz dodać .strip () na końcu lub podobną poprawkę.check_output()
zamiast.communicate()
tutaj:print(subprocess.check_output("echo hi", shell=True, universal_newlines=True), end="")
Odpowiedzi:
Polecenie echo domyślnie zwraca znak nowego wiersza
Porównaj z tym:
print(subprocess.Popen("echo -n hi", \ shell=True, stdout=subprocess.PIPE).communicate()[0])
Jeśli chodzi o b poprzedzające ciąg, oznacza to, że jest to sekwencja bajtów, która jest równoważna zwykłemu ciągowi w Pythonie 2.6+
http://docs.python.org/3/reference/lexical_analysis.html#literals
źródło
Symbol
b
wskazuje, że to, co maszbytes
, jest binarną sekwencją bajtów, a nie ciągiem znaków Unicode. Podprocesy wysyłają bajty, a nie znaki, więc to właśniecommunicate()
zwraca.bytes
Typ nie jest bezpośrednioprint()
w stanie, więc jesteś jest pokazanyrepr
zbytes
masz. Jeśli znasz kodowanie bajtów, które otrzymałeś z podprocesu, możesz użyć ichdecode()
do przekształcenia ich w plik drukowalnystr
:>>> print(b'hi\n'.decode('ascii')) hi
Oczywiście ten konkretny przykład działa tylko wtedy, gdy faktycznie otrzymujesz ASCII z podprocesu. Jeśli to nie jest ASCII, pojawi się wyjątek:
>>> 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…
Nowa linia jest częścią
echo hi
wyniku.echo
Zadanie polega na wyświetleniu przekazanych parametrów, po których następuje znak nowej linii. Jeśli nie jesteś zainteresowany białymi znakami otaczającymi wyjście procesu, możesz użyć w tenstrip()
sposób:>>> b'hi\n'.strip() b'hi'
źródło
os.popen
zwraca ciągi tekstowe, czy istnieje sposób, abysubprocess.Popen
również je zwrócić, zamiast ciągów bajtów.universal_newlines
która powoduje, żePopen
obiekt przyjmuje i zwraca ciągi tekstowe.check_output("dir")
, wyodrębnienie nazwy pliku z wyjścia, a następnie próba uzyskania do niego dostępu nieopen
powiedzie się, jeśli nazwa pliku zawiera niemieckie umlauty. To może być błąd.Jak wspomniano wcześniej,
echo hi
faktycznie wracahi\n
, co jest oczekiwanym zachowaniem.Ale prawdopodobnie chcesz po prostu uzyskać dane w „odpowiednim” formacie i nie zajmować się kodowaniem. Wystarczy, że przekażesz
universal_newlines=True
opcjęsubprocess.Popen()
polubienia:>>> import subprocess >>> print(subprocess.Popen("echo hi", shell=True, stdout=subprocess.PIPE, universal_newlines=True).communicate()[0]) hi
W ten sposób sam
Popen()
zastąpi te niechciane symbole.źródło
universal_newlines=True
działał jak urok. To powinna być akceptowana odpowiedź, moim skromnym zdaniem ...universal_newlines=True
inPopen
(aby pozbyć sięb''
), jak i astrip()
na otrzymanym ciągu.universal_newlines
jest teraz tylko zgodnym wstecz aliasemtext
parametru, który jest bardziej przejrzysty, ale tylko w Pythonie 3.7 i nowszych.b jest reprezentacją bajtową, a \ n jest wynikiem wyjścia echa.
Następujące spowoduje wydrukowanie tylko danych wyników
import subprocess print(subprocess.Popen("echo hi", shell=True,stdout=subprocess.PIPE).communicate()[0].decode('utf-8').strip())
źródło