from subprocess import PIPE,Popen

p = Popen("ls -l",shell=True,stderr=PIPE,stdout=PIPE)
(out,err) = p.communicate()
print(out, err)

В приведенном выше вызове Popen, если я удалю stdout=PIPE, я получаю новую строку после каждого перечисления на ls -l в выводе. Но если использовать stdout=PIPE, у меня будет отображаться \n, а не новая строка, как показано ниже.

b'total 67092\n-rw-r--r--  1 root root      171 May 27 09:08 new.py\n-rw-r--r--  1   
    root root       74 May 12 18:14 abcd.conf\n-rwxr-xr-x  1 root root     5948 May 13 13:21 abxyz.sh\ndrwxr-xr-x  2 root root     4096 May 13
12:39 log\ndrwxrwxrwx  3 root root     4096 May 14 16:02
newpy\n-rw-r--r--  1 root root      134 May 27 10:13
pipe.py\n-rw-r--r--  1 root root      155 May 27 10:07
proc.py\ndrwxrwxrwx  3 root root     4096 May 14 14:29 py\ndrwxr-xr-x
16 1000 1000\n' b''

Как точно работает PIPE в случае subprocess.Popen? Зачем нам это нужно? Я получил нормальный вывод без его использования? Используем ли мы это для получения как stderr, так и stdout?

4
user966588 27 Май 2013 в 14:26

1 ответ

Лучший ответ

Удалите вызов print(), чтобы увидеть разницу.

Если вы не передаете вывод ls в Python, он вместо этого отображается непосредственно на вашем терминале; его вывод идет на ваш терминал. Если вы передадите его на Python, вы увидите все содержимое как байты, включая байты новой строки (представленные как \n).

Расшифруйте результаты, если хотите, чтобы символы новой строки печатались буквально:

print(out.decode('utf8'))
5
Martijn Pieters 27 Май 2013 в 14:27
Ох. Я видел это без печати. Он отображается прямо на моем экране. Я думал, что печатаю. Что произойдет, если я использую stdin без ТРУБЫ?
 – 
user966588
27 Май 2013 в 14:38
Также после использования stdout=PIPE на экране не отображается stderr. Почему? не следует ли только PIPE stdout и display stderr.
 – 
user966588
27 Май 2013 в 14:44
ls записывает в дескриптор файла stdout, который, когда вы его не используете, напрямую подключается к вашему терминалу. Когда вы перенаправляете его в Python, вы захватываете все, что ему пишет ls. ls не ничего пишет stderr. Когда вы используете PIPE для stderr, вы видите, что ваша переменная err пуста (b'' - это пустое байтовое значение).
 – 
Martijn Pieters
27 Май 2013 в 14:51
Если я не использую stderr=PIPE в Popen и print(err), я получаю None в выводе для err. Мой вопрос заключался в том, почему этот None не отображается прямо на экране. Потому что он отображался без PIPE для stdout и stderr.
 – 
user966588
27 Май 2013 в 15:01
Вы не захватили stderr, поэтому python возвращает None, потому что требуется значение. ls не печатал None; None не является значением Python, обозначающим пустое значение.
 – 
Martijn Pieters
27 Май 2013 в 15:31