15

チェーンの最初のプロセスで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)

2番目のプロセスでshell=Trueは問題ではないようです。これは予想される動作ですか?

4

1 に答える 1

19

を渡す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)
于 2012-05-19T01:03:18.577 に答える