python管道命令_关于python:如何使用带有管道的`subprocess`命令

我想用subprocess.check_output()和ps -A | grep 'process_name'。我试过各种各样的解决办法,但到目前为止都没用。有人能指导我怎么做吗?

相关:如何使用subprocess.popen通过管道连接多个进程?

psutil允许以可移植的方式获取进程信息。

要将管道与subprocess模块一起使用,必须通过shell=True。

然而,由于各种原因,这并不是真正的明智之举,尤其是安全性。相反,分别创建ps和grep进程,并将输出从一个进程传输到另一个进程,如下所示:

ps = subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)

output = subprocess.check_output(('grep', 'process_name'), stdin=ps.stdout)

ps.wait()

然而,在您的特定情况下,简单的解决方案是对输出调用subprocess.check_output(('ps', '-A')),然后调用str.find。

+1用于分离输出/输入以避免使用shell=True。

别忘了,错误subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1只是意味着grep没有发现任何东西,所以这是正常的行为。

当我们已经有产出的时候,为什么我们需要ps.wait()。ps.wait.__doc__等待子进程终止,但子进程的内容似乎已放入output变量中。

使用python函数而不是grep会更好,但我发现str.find(现在)被认为是不推荐使用的:docs.python.org/2/library/…

@makish您看到的是string.find,它已经被弃用,取而代之的是str.find(即,str对象上的方法find)。

注:如果grep过早死亡;如果ps产生足够的输出来填充其OS管道缓冲区(因为您在父级中没有调用ps.stdout.close(),则它可能无限期挂起。交换起始顺序以避免

使用ps.wait()而不是output.wait()的原因是什么?

@因为output是一个字节字符串,没有wait方法。

关于为什么不使用shell=True的一些实际解释:stackoverflow.com/questions/3172470/…

如果有多个管道操作,我应该按顺序为每个命令执行ps.wait()?@泰门

在我的例子中,我使用的是yes | accept_licenses,由于yes本身并没有终止,所以我必须使用time.wait(10); ps.terminate()而不是ps.wait()。

你使用元组而不是popen中的列表有什么原因吗?为什么你不使用subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)而不是subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)?这是我第一次遇到这种用法,我想知道是否有原因。

@eaydin:lists和tuples都是序列,所以两者都可以工作。后者不是可变的,可能创建得更快(尽管我从未测试过这个假设)。在这种特殊情况下,差异可能不显著。

或者,您可以始终在子流程对象上使用Communicate方法。

cmd ="ps -A|grep 'process_name'"

ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)

output = ps.communicate()[0]

print output

communication方法返回标准输出和标准错误的元组。

我认为使用communicate比wait更好。有这样的警告:"当使用stdout=pipe和/或stderr=pipe时,这将死锁,并且子进程生成足够的输出到管道,从而阻止等待OS管道缓冲区接受更多数据。使用communication()避免这种情况。"

为了澄清保罗上面的评论,警告是等待,而不是沟通——也就是说,这是他说沟通更好的原因。

是的,公认的shell=true的是很糟糕的。

请参阅有关使用子流程设置管道的文档:http://docs.python.org/2/library/subprocess.html替换shell管道

我没有测试以下代码示例,但它应该大致符合您的要求:

query ="process_name"

ps_process = Popen(["ps","-A"], stdout=PIPE)

grep_process = Popen(["grep", query], stdin=ps_process.stdout, stdout=PIPE)

ps_process.stdout.close()  # Allow ps_process to receive a SIGPIPE if grep_process exits.

output = grep_process.communicate()[0]

在检查这个失败后,请参阅下面泰门的答案,找到一些可以不弄脏周围的东西。

subprocess.check_输出在python 2.6.9中似乎不存在

Jkalavis解决方案很好,但是我会添加一个改进来使用shlex,而不是shell=true。下面我将列出查询时间

#!/bin/python

import subprocess

import shlex

cmd ="dig @8.8.4.4 +notcp www.google.com|grep 'Query'"

ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)

output = ps.communicate()[0]

print output

干杯,

为什么是Shellx而不是Shell?

另外,尝试使用'pgrep'命令而不是'ps -A | grep 'process_name'命令。

显然,如果您想要获取进程ID

您可以在sh.py中尝试管道功能:

import sh

print sh.grep(sh.ps("-ax"),"process_name")

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值