通过Python子模块管道在壳(piping in shell via Python subproc

2019-06-24 02:30发布

所以,我想查询一个给定的机器上的前3名CPU“密集”的过程中,我发现这个shell命令做到这一点: ps -eo pcpu,pid,user,args | sort -k 1 -r | head -3 ps -eo pcpu,pid,user,args | sort -k 1 -r | head -3

我想用Python脚本里面这个数据,所以我需要能够通过捕捉上面的命令的输出subprocess模块。 下面的工作,但只返回一个字符串,巨大的,因为我没有把它限制为前3名:

psResult = subprocess.check_output(['ps', '-eo', 'pcpu,user,args'])

我不太清楚这是怎么subprocess.check_output工程..在微薄的尝试我想:

subprocess.check_output(['ps', '-eo', 'pcpu,user,args', '|', 'sort', '-k', '1', '-r', '|', 'head', '-3'])

这给了我一个错误: ps: illegal argument: |

如何使用管道| 内部的Python符号,或者使用一些其他的方式来进行排序,而无需做难以置信量解析由返回的巨大串的psResult = subprocess.check_output(['ps', '-eo', 'pcpu,user,args'])

谢谢! 问候,-kstruct

Answer 1:

您可以通过shell=True参数执行一个简单的shell命令:

import subprocess
subprocess.check_output('ps -eo pcpu,pid,user,args | sort -k 1 -r | head -3',
                        shell=True)

另外,用ps和Python的内置字符串函数像这样的排序选项:

raw = subprocess.check_output('ps -eo pcpu,pid,user,args --sort -pcpu')
first_three_lines = list(raw.split('\n'))[:3]


Answer 2:

有些人建议使用shell=True ,而这个答案是好的,如果你正在传递信任的输入对外壳。 然而, shell=True介绍了一些不安全因素。 为安全起见,该文档提出以下建议:

output=`dmesg | grep hda`
# becomes
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]


Answer 3:

如果你使用它应该工作:

subprocess.check_output("ps -eo pcpu,pid,user,args | sort -k 1 -r | head -3", shell=True)

然后命令完全一样使用运行/bin/sh ,所以管会工作。



Answer 4:

为什么在所有使用外部命令? 使用psutil :

import psutil
def cpu_percentage(proc):
    try:
        return proc.get_cpu_percent()
    except psutil.AccessDenied:
        return float('-inf')

top3 = sorted(psutil.process_iter(), key=cpu_percentage, reverse=True)[:3]
for proc in top3:
    # do whatever


文章来源: piping in shell via Python subprocess module