Подтвердить что ты не робот

Почему Popen.communicate() возвращает b'hi\n 'вместо' hi '?

Может кто-нибудь объяснить, почему результат, который я хочу, "привет", предшествует букве "b" и следует за новой линией?

Я использую Python 3.3

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

Этот дополнительный "b" не появляется, если я запускаю его с помощью python 2.7

4b9b3361

Ответ 1

Команда echo по умолчанию возвращает символ новой строки

Сравните с этим:

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

Что касается b, предшествующего строке, это указывает, что это байтовая последовательность, которая эквивалентна нормальной строке в Python 2. 6+

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

Ответ 2

b указывает, что у вас есть bytes, который представляет собой двоичную последовательность байтов, а не строку символов Unicode, Подпроцессы выводят байты, а не символы, так что возвращается communicate().

Тип bytes не доступен непосредственно print(), поэтому вам показывают repr bytes. Если вы знаете кодировку полученных вами байтов из подпроцесса, вы можете использовать decode() для преобразования их в печатный str:

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

Конечно, этот конкретный пример работает только в том случае, если вы фактически получаете ASCII из подпроцесса. Если это не ASCII, вы получите исключение:

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

Новая строка является частью вывода echo hi. Задача echo состоит в том, чтобы выводить параметры, которые вы передаете, а затем новую строку. Если вас не интересует пробел, окружающий вывод процесса, вы можете использовать strip() так:

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

Ответ 3

Как упоминалось ранее, echo hi действительно возвращает hi\n, что является ожидаемым поведением.

Но вы, вероятно, хотите просто получить данные в "правильном" формате и не иметь дело с кодировкой. Все, что вам нужно сделать, это передать universal_newlines=True вариант для subprocess.Popen():

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

Таким образом, Popen() заменит эти нежелательные символы сам по себе.

Ответ 4

b - это представление байтов, а \n - результат выхода эха.

Далее будут напечатаны только данные результата

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

Ответ 5

'#!/usr/bin/python3
   import subprocess 
   nginx_ver = subprocess.getstatusoutput("nginx -v")
   print(nginx_ver)'


Output:  (0, 'nginx version: nginx/1.12.1')