8

所以我试图查询给定机器上前 3 个 CPU “密集型”进程,我发现这个 shell 命令可以做到这一点: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

4

4 回答 4

12

您可以传递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]
于 2012-05-01T22:59:26.147 回答
11

其他一些人建议使用shell=True,如果您将受信任的输入传递给 shell ,这个答案很好。但是,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]
于 2013-02-26T22:29:40.180 回答
1

如果您使用它应该可以工作:

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

然后使用 完全像这样运行命令/bin/sh,因此管道将起作用。

于 2012-05-01T22:58:37.567 回答
1

为什么要使用外部命令?使用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
于 2012-05-03T20:19:04.510 回答