2012-05-01 14 views
5

Więc próbuję kwerendy na górze 3 CPU „Intensive” procesów na danej maszynie, i znalazłem to polecenie powłoki, aby to zrobić: ps -eo pcpu,pid,user,args | sort -k 1 -r | head -3rurociągów w powłoce poprzez moduł Pythona podproces

chcę używać te dane w skrypcie Python, więc muszę mieć możliwość przechwycenia danych wyjściowych powyższego polecenia za pomocą modułu subprocess. Poniższy działa, ale po prostu zwraca ogromny ciąg ponieważ ja nie ograniczając go do góry 3:

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

nie jestem pewien, jak to działa .. subprocess.check_output w skromnej próbie próbowałem:

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

Który daje mi błąd: ps: illegal argument: |

Jak mogę użyć rury | symbol wewnątrz Python lub użyj innego sposób sortowania bez konieczności wykonywania niewiarygodnych ilości analizowania na wielkim ciągu zwracanym przez psResult = subprocess.check_output(['ps', '-eo', 'pcpu,user,args'])?

Dzięki! Pozdrawiam, -kstruct

+0

Można napisać skrypt zawierający kod z rur, a następnie zadzwonić, że z modułu subprocess – jedwards

Odpowiedz

10

Można zdać shell=True argumentu, aby wykonać prostą komendę powłoki:

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

Można także użyć opcji sortowania PS i Pythona wbudowanych funkcji łańcuchowych tak:

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

powinno działać, jeśli używasz:

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

następnie polecenie jest uruchamiane dokładnie tak, jak to przy użyciu /bin/sh, więc rury będzie działać.

1

Why w ogóle używać zewnętrznych poleceń? Użyj 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

Inni sugerowali, używając shell=True i this answer jest w porządku, jeśli jesteś przejazdem zaufany wejście do powłoki. Jednak shell=True wprowadza pewne niepewności. Dla bezpieczeństwa, docs Zalecamy:

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]