2011-07-21 10 views
19

Jak uruchomić polecenie z rurą |?Jak uruchomić "ps cax | grep something" w języku Python?

Moduł podproces wydaje kompleks ...

Czy istnieje coś takiego jak

output,error = `ps cax | grep something` 

jak w skrypcie?

+0

Nie rób tego z 'podprocesorem'. Z powłoką jest to o wiele łatwiejsze. Rzeczywiście, jest to jedyna rzecz, którą robi najlepiej skorupa. –

Odpowiedz

38

Zobacz Replacing shell pipeline:

import subprocess 

proc1 = subprocess.Popen(['ps', 'cax'], stdout=subprocess.PIPE) 
proc2 = subprocess.Popen(['grep', 'python'], stdin=proc1.stdout, 
         stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

proc1.stdout.close() # Allow proc1 to receive a SIGPIPE if proc2 exits. 
out, err = proc2.communicate() 
print('out: {0}'.format(out)) 
print('err: {0}'.format(err)) 

PS. Używanie shell=True może być niebezpieczne. Zobacz na przykład the warning w dokumentach.


Istnieje również sh module co może sprawić subprocess skryptów w Pythonie dużo bardziej przyjemne:

import sh 
print(sh.grep(sh.ps("cax"), 'something')) 
+0

Świetne odwołanie do modułu sh, bardzo polecam. –

+0

'sh.grep (sh.ps ('aux', _piped = True), 'coś')' - pracował dla mnie –

+0

@unutbu, Czy mógłbyś wyjaśnić bardziej szczegółowo, dlaczego powinno się wywoływać 'proc1.stdout.close()' ? – SangminKim

8
import subprocess 

process = subprocess.Popen("ps cax | grep something", 
          shell=True, 
          stdout=subprocess.PIPE, 
          ) 
stdout_list = process.communicate()[0].split('\n') 
+0

coś w grep coś byłoby zmienną, powinienem zbudować ciąg "ps cax | grep something" ze zmienną, aby go uruchomić? czy jest inny sposób robienia tego? – eugene

+1

http://docs.python.org/library/stdtypes.html#string-formatting lub http://docs.python.org/library/string.html#string-formatting. Zasadniczo, '' grep% s'% zmienna'. – agf

+3

@Eugene: Możesz skonstruować ciąg za pomocą zmiennej, ale uważaj, skąd pochodzi zmienna. To znaczy. upewnij się, że nie pochodzi od użytkownika, który mógłby "coś" uczynić w "coś"; rm -rf/"'. Budowanie wyrażeń do uruchomienia za pomocą powłoki = True jest możliwym zagrożeniem bezpieczeństwa. –

2
import os 

os.system('ps -cax|grep something') 

Jeśli chcesz wymienić argumentu grep z jakiejś zmiennej:

os.system('ps -cax|grep '+your_var) 
+2

To nie daje wyniku polecenia. –

+0

@Kirk Strauser, nie możesz uzyskać danych wyjściowych? Przetestowałem to zarówno w interpretera interaktywnego python i uruchomieniu go jako skrypt, działa zgodnie z oczekiwaniami (moja wersja python jest 2.7.1, jeśli to pomaga) –

+3

'os.system' zwraca tylko kod zakończenia podprocesu. Jeśli używasz go w interaktywnym monicie i widzisz wyjście ps, to dlatego, że ps pisze do portera. Python nie przechwytuje tego wyjścia. Spróbuj sam: uruchom 'a = os.system ('ls')'. Nadal będziesz widzieć wyjście ls, a 'a' będzie 0 (zakładając, że z jakiegoś powodu ls nie zawodzi). –

14

Już zaakceptowałeś odpowiedź, ale:

Czy naprawdę potrzebujesz Potrzebujesz do używania grep? Chciałbym napisać coś takiego:

import subprocess 
ps = subprocess.Popen(('ps', 'cax'), stdout=subprocess.PIPE) 
output = ps.communicate()[0] 
for line in output.split('\n'): 
    if 'something' in line: 
     ... 

ta ma zalety nieobejmujące shell=True i jego ryzykownych, nie widelec off oddzielnego procesu grep i wygląda strasznie dużo jak rodzaj Pythonie chcesz napisać do przetwarzania obiektów podobnych do plików danych.

5

Upuść podproces "ps" i powoli wycofaj się! :)

Zamiast tego należy użyć modułu psutil.

+2

Chcę użyć psutil, ale ta odpowiedź nie jest bardzo pomocna bez pokazywania, jak to by było zrobione. –