Python—如何使用管道执行shell命令,但不使用';shell=True';?

Python—如何使用管道执行shell命令,但不使用';shell=True';?,python,subprocess,pipe,Python,Subprocess,Pipe,我想用Python执行下面的shell命令并获得输出 echo This_is_a_testing | grep -c test 我可以用这个python代码在python中执行上面的shell命令 >>> import subprocess >>> subprocess.check_output("echo This_is_a_testing | grep -c test", shell=True) '1\n' 但是,由于我不想使用“

我想用Python执行下面的shell命令并获得输出

echo This_is_a_testing | grep -c test
我可以用这个python代码在python中执行上面的shell命令

>>> import subprocess
>>> subprocess.check_output("echo This_is_a_testing | grep -c test", shell=True)
'1\n'
但是,由于我不想使用“shell=True”选项,我尝试了以下python代码

>>> import subprocess
>>> p1 = subprocess.Popen(["echo", "This_is_a_testing"], stdout=subprocess.PIPE)
>>> p2 = subprocess.Popen(["grep", "-c", "test"], stdin=p1.stdout)
>>> p1.stdout.close()
>>> p2.communicate()
(None, None)
我想知道为什么输出为“无”,因为我已经参考了网页中的描述:

我是否遗漏了代码中的一些要点?有什么建议/想法吗?提前感谢。

手册:

要在结果元组中获得除None之外的任何内容,您需要 标准输出=管道和/或标准输出=管道

请看这里:

>>> import subprocess
>>> p1 = subprocess.Popen(["echo", "This_is_a_testing"], stdout=subprocess.PIPE)
>>> p2 = subprocess.Popen(["grep", "-c", "test"], stdin=p1.stdout)
>>> 1
p1.stdout.close()
>>> p2.communicate()
(None, None)
>>>
在这里,当您编写
p2=subprocess.Popen([“grep”、“-c”、“test”]、stdin=p1.stdout)
后,您将得到1作为输出,请不要在您的问题上下文中忽略此输出

如果这是您想要的,则将
stdout=subprocess.PIPE
作为参数传递给第二个
Popen

>>> p1 = subprocess.Popen(["echo", "This_is_a_testing"], stdout=subprocess.PIPE)
>>> p2 = subprocess.Popen(["grep", "test"], stdin=p1.stdout, stdout=subprocess.PIPE)
>>> p2.communicate()
('This_is_a_testing\n', None)
>>>

虽然接受的答案是正确的/有效的,但另一种选择是使用
Popen.communicate()
方法将内容传递给进程的stdin:

>>> import subprocess
>>> p2 = subprocess.Popen(["grep", "-c", "test"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
>>> p2.communicate("This_is_a_testing")
('1\n', None)
>>> print p2.returncode
0
>>>>
这就解决了如果python脚本本身中已经知道输出,则只需执行另一个命令来重定向其输出的问题


然而,
communicate
有一个副作用,它会等待进程终止。如果需要/需要异步执行,则使用两个进程可能是更好的选择。

答案与前面提到的类似,格式很少。我希望在Python3上使用管道获得与普通shell命令完全相同的输出

import subprocess

p1 = subprocess.Popen(["ls", "-l", "."], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep", "May"], stdin=p1.stdout, stdout=subprocess.PIPE)


for s in (str(p2.communicate())[2:-10]).split('\\n'):
    print(s)

现在我知道,要使
p2.communicate()
工作,我必须在代码
p2=…
中添加
stdout=subprocess.PIPE
。谢谢。如果在p1结果中发生错误,我如何获得错误?这是我的问题,你能帮忙吗?它在内部使用shell。OP明确表示:“我不想使用“shell=True”选项”谢谢。这正是我在Python中搜索“如何使用管道执行shell命令”时所要寻找的。我必须使用commands.getoutput而不是subprocess.getoutput才能使其工作。check_output()?在Python 2.7中不存在,在Python 3.6.6中是否相关:
>>> import subprocess
>>> p2 = subprocess.Popen(["grep", "-c", "test"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
>>> p2.communicate("This_is_a_testing")
('1\n', None)
>>> print p2.returncode
0
>>>>
import subprocess

p1 = subprocess.Popen(["ls", "-l", "."], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep", "May"], stdin=p1.stdout, stdout=subprocess.PIPE)


for s in (str(p2.communicate())[2:-10]).split('\\n'):
    print(s)