Почему shell = True ест мой подпроцесс. Открыть стандартный вывод?

Кажется, что использование shell = True в первом процессе цепочки каким-то образом отбрасывает stdout из последующих задач:

p1 = Popen(['echo','hello'], stdout=PIPE)
p2 = Popen('cat', stdin=p1.stdout, stdout=PIPE)
p2.communicate()
# outputs correctly ('hello\n', None)

Заставить первый процесс использовать shell = True как-то убивает вывод ...

p1 = Popen(['echo','hello'], stdout=PIPE, shell=True)
p2 = Popen('cat', stdin=p1.stdout, stdout=PIPE)
p2.communicate()
# outputs incorrectly ('\n', None)

shell = True для второго процесса, похоже, не имеет значения. Это ожидаемое поведение?

10 голосов | спросил Jake Biesinger 19 Mayam12 2012, 04:55:52

1 ответ


0

Когда вы передаете shell=True, Popen ожидает один строковый аргумент, а не список. Поэтому, когда вы делаете это:

p1 = Popen(['echo','hello'], stdout=PIPE, shell=True)

Что происходит, это:

execve("/bin/sh", ["/bin/sh", "-c", "echo", "hello"], ...)

То есть он вызывает sh -c "echo" и hello фактически игнорируется (технически он становится позиционным аргументом оболочки). Таким образом, оболочка выполняет echo, которая печатает \n, именно поэтому вы видите это в своем выводе.

Если вы используете shell=True, вам нужно сделать это:

  p1 = Popen('echo hello', stdout=PIPE, shell=True)
ответил larsks 19 Mayam12 2012, 05:03:18

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132