Python - 如何使用管道执行shell命令,但没有'shell = True'?
Posted
技术标签:
【中文标题】Python - 如何使用管道执行shell命令,但没有\'shell = True\'?【英文标题】:Python - how to execute shell commands with pipe, but without 'shell=True'?Python - 如何使用管道执行shell命令,但没有'shell = True'? 【发布时间】:2012-03-12 16:47:55 【问题描述】:我有一个案例想在 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
我是否遗漏了代码中的一些要点?有什么建议/想法吗?提前致谢。
【问题讨论】:
相关:How do I use subprocess.Popen to connect multiple processes by pipes? 【参考方案1】:请看这里:
>>> 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)
>>>
【讨论】:
现在我知道要让p2.communicate()
工作,我必须在代码p2 = ...
中添加stdout=subprocess.PIPE
。谢谢。
如果它发生在 p1 结果中,我怎么能得到错误?这是我的问题,你能帮忙吗? ***.com/questions/40467105/…【参考方案2】:
>>> import subprocess
>>> mycmd=subprocess.getoutput('df -h | grep home | gawk \' print $1 \' | cut -d\'/\' -f3')
>>> mycmd
'sda6'
>>>
【讨论】:
它在内部使用 shell。 OP 明确表示:“我不想使用“shell=True”选项” 谢谢。这正是我在 Python 中搜索“如何使用管道执行 shell 命令”时要寻找的内容。 我必须使用 commands.getoutput 而不是 subprocess.getoutput 才能工作 不是subprocess.check_output()
?
在 Python 2.7 中不存在,在 Python 3.6.6 中存在【参考方案3】:
来自手册:
要在结果元组中获得除 None 以外的任何内容,您需要给出 stdout=PIPE 和/或 stderr=PIPE
p2 = subprocess.Popen(["grep", "-c", "test"], stdin=p1.stdout, stdout=subprocess.PIPE)
【讨论】:
【参考方案4】:虽然接受的答案正确/有效,但另一种选择是使用 Popen.communicate()
方法将某些内容传递给进程的标准输入:
>>> 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
有副作用,它会等待进程终止。如果需要/希望使用两个进程异步执行可能是更好的选择。
【讨论】:
【参考方案5】:答案与前面提到的类似,格式很少。我想在 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)
【讨论】:
以上是关于Python - 如何使用管道执行shell命令,但没有'shell = True'?的主要内容,如果未能解决你的问题,请参考以下文章
linux shell脚本执行命令时创建子进程问题(特定的情况,例如后台运行管道分支或子shell等,脚本可能会创建子进程执行命令)