通过Python子进程模块在shell中进行管道

ade*_*rtc 6 python shell subprocess pipe

所以我试图在给定的机器上查询前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

phi*_*hag 11

您可以传递shell=True参数以执行plain shell命令:

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

或者,使用ps的排序选项和Python的内置字符串函数,如下所示:

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


sen*_*rle 6

其他一些人建议使用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]
Run Code Online (Sandbox Code Playgroud)