Subprocess popen stdout
Я изучаю subprocess
, но у меня есть небольшая путаница с этим кодом:
import subprocess
proc = subprocess.Popen('lspci', stdout=subprocess.PIPE)
for line in proc.stdout:
print(line)
Вывод:
b'00:00.0 Host bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller (rev 09)\n'
b'00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller (rev 09)\n'
Как вы можете видеть, выход формируется. Но я не знаю, почему в конце символ b''
и \n
.
Если я запустил эту команду в моем терминале, то не эти char.
Нормальный выход:
00:00.0 Host bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller (rev 09)
00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller (rev 09)
Как я могу удалить их?
Ответы
Ответ 1
Вероятно, вы используете python3 - python изменил способ чтения/записи определенных объектов, и теперь существует реальный объект bytes()
. Чтобы получить нужную строку, вам просто нужно:
print(line.decode("utf8")) ## or some encoding; that one should print anything though
Вам также может понадобиться снять новую строку (\n
) с вашего вывода; Я не помню, как stdout
выполняет буферизацию/отчетность:
print(line.decode("utf8").strip())
Ответ 2
b''
- это текстовое представление для объектов bytes
в Python 3.
Чтобы напечатать байты как есть, используйте двоичный поток - sys.stdout.buffer
:
#!/usr/bin/env python3
import sys
from subprocess import Popen, PIPE
with Popen('lspci', stdout=PIPE, bufsize=1) as process:
for line in process.stdout: # b'\n'-terminated lines
sys.stdout.buffer.write(line)
# do something with line here..
Чтобы получить вывод в виде текста (строка Юникода), вы можете использовать параметр universal_newlines=True
:
#!/usr/bin/env python3
from subprocess import Popen, PIPE
with Popen('lspci', stdout=PIPE, bufsize=1, universal_newlines=True) as process:
for line in process.stdout: # b'\n', b'\r\n', b'\r' are recognized as newline
print(line, end='')
# do something with line here..
locale.getpreferredencoding(False)
кодирование символов используется для декодирования вывода.
Если дочерний процесс использует другую кодировку, вы можете явно указать его с помощью io.TextIOWrapper()
:
#!/usr/bin/env python3
import io
from subprocess import Popen, PIPE
with Popen('lspci', stdout=PIPE, bufsize=1) as process:
for line in io.TextIOWrapper(process.stdout, encoding='utf-8'):
print(line, end='')
# do something with line here..
Для кода Python 2 и ссылок на возможные проблемы см. Python: прочитайте потоковый ввод из subprocess.communicate()
Ответ 3
Я думаю, вы используете python 3:
b для байтов, и это указывает, что это байтовая последовательность, которая эквивалентна нормальной строке в Python 2.6 +
см. https://docs.python.org/3/reference/lexical_analysis.html#literals