2012-05-01 105 views
5

所以我想查詢一個給定的機器上的前3名CPU「密集」的過程中,我發現這個shell命令做到這一點:ps -eo pcpu,pid,user,args | sort -k 1 -r | head -3通過Python子進程模塊管殼

我想用這些數據在一個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

+0

你可以寫含管道代碼中的shell腳本,然後調用從子模塊 – jedwards

回答

10

您可以通過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] 
1

如果你使用它應該工作:

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

然後運行命令正是這樣使用/bin/sh,使管會工作。

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 
4

有些人已經使用shell=True建議,並this answer是好的,如果你正在傳遞信任的輸入對外殼。然而,shell=True引入了一些不安全感。出於安全考慮,docs提出以下建議:

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]