python - 为什么 shell=True 会吃掉我的 subprocess.Popen stdout?

标签 python subprocess pipe popen

似乎在链的第一个进程中使用 shell=True 以某种方式从下游任务中删除标准输出:

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 似乎无关紧要。这是预期的行为吗?

最佳答案

当您传递 shell=True 时,Popen 需要一个字符串参数,而不是一个列表。所以当你这样做时:

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

这是怎么回事:

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

也就是说,它调用 sh -c "echo",而 hello 被有效地忽略(技术上它成为 shell 的位置参数)。因此 shell 运行 echo,打印 \n,这就是为什么您会在输出中看到它。

如果你使用shell=True,你需要这样做:

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

关于python - 为什么 shell=True 会吃掉我的 subprocess.Popen stdout?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10661457/

相关文章:

python - Python 中子进程 PIPE 的非阻塞读取,一次一个字节

python - 找到 2 个堆栈的交集的最快和最有效的方法

python - 不允许操作 : Server-setsockopt() error for SO_BINDTODEVICE

c - 即使添加了 #include <stdio.h> 也隐式声明了 popen

python - 在 Linux 上重定向 `stdin`?还是我做错了?

python - 从 python 与 bash 交互

python - Odoo bool 图?

python - 重复从字符串中删除字符

python - 在层次结构中显示类别和子类别

python - 以 sudo 身份运行 python 脚本的一部分