Python - 如何用管道执行shell命令?

时间:2012-02-22 10:54:24

标签: 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'

但是,由于我不想使用“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)

我想知道为什么输出为“无”,因为我已经参考了网页中的说明:http://docs.python.org/library/subprocess.html#subprocess.PIPE

我错过了代码中的一些要点吗?有什么建议/想法吗?提前谢谢。

5 个答案:

答案 0 :(得分:31)

请看这里:

>>> 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)
>>>

答案 1 :(得分:26)

从手册:

  

在结果元组中得到除None之外的任何东西,你需要给出   stdout = PIPE和/或stderr = PIPE

p2 = subprocess.Popen(["grep", "-c", "test"], stdin=p1.stdout, stdout=subprocess.PIPE)

答案 2 :(得分:17)

>>> import subprocess

>>> mycmd=subprocess.getoutput('df -h | grep home | gawk \'{ print $1 }\' | cut -d\'/\' -f3')

>>> mycmd 

'sda6'

>>>

答案 3 :(得分:4)

虽然接受的答案是正确/有效的,但另一个选择是使用let url = URL(string: "http://www.sourcefreeze.com")! myWebView.load(URLRequest(url: url)) 方法将某些内容传递给进程'stdin:

Popen.communicate()

如果输出在python脚本本身已知,则解决了执行另一个命令只是为了重定向它的输出的需要。

但是>>> 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 >>>> 有副作用,它等待进程终止。如果需要/期望使用两个进程进行异步执行可能是更好的选择。

答案 4 :(得分:1)

答案与前面提到的类似,但格式很少。我想在python 3上使用管道获得与普通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)