2013-02-06 12 views

Odpowiedz

31

Z 3.3 documentation:

stdin, stdout i stderr podać standardowe wejście wykonywanego programu, standard wyjścia i standardowe uchwyty plików błędów, odpowiednio. Poprawne wartości to PIPE, DEVNULL, istniejący deskryptor pliku (dodatnia liczba całkowita), istniejący obiekt pliku i Brak.

Więc:

subprocess.check_call(['java', '-jar', 'foo.jar'], stdout=subprocess.DEVNULL) 

ta istnieje tylko w 3.3 i później. Ale dokumentacja mówi:

DEVNULL wskazuje, że zostanie użyty specjalny plik os.devnull.

I os.devnull istnieje powrót do 2,4 (przed istnieniem subprocess). Tak, można zrobić to samo ręcznie:

with open(os.devnull, 'w') as devnull: 
    subprocess.check_call(['java', '-jar', 'foo.jar'], stdout=devnull) 

pamiętać, że jeśli robisz coś bardziej skomplikowanego, które nie mieszczą się w jednej linii, trzeba zachować devnull otwarty dla całego życia Popen obiekt, a nie tylko jego konstrukcja. (To znaczy, umieścić całość wewnątrz rachunku with.)

Zaletą przekierowanie do /dev/null (POSIX) lub NUL: (Windows) jest to, że nie tworzyć niepotrzebnego rurę, i, co ważniejsze, można” • przebiegać w przypadkach skrajnych, w których podproces blokuje zapisywanie do tej rury.

Wadą jest to, że teoretycznie, subprocess może działać na niektórych platformach, których nie ma os.devnull. Jeśli zależy ci tylko na CPython na POSIX i Windows, PyPy i Jython (który jest większości z was), to nigdy nie będzie problemu. W innych przypadkach przetestuj przed dystrybucją swojego kodu.

+0

+1: dla devnull. Upewnij się, że 'devnull' pozostaje otwarty, podczas gdy podproces jest aktywny (instrukcja" with "oznacza inaczej). Ostatni akapit wydaje się niepotrzebny: DEVNULL jest implementowany za pośrednictwem os.devnull w CPython. os.devnull współpracuje z Jythonem. – jfs

+0

@ J.F.Sebastian: Po 'check_call' (który znajduje się wewnątrz' with'), 'devnull' nie jest już potrzebny. Ale tak, może powinienem wyjaśnić, że dla bardziej skomplikowanych przypadków użycia, które nie mieszczą się w jednej linii, cała sprawa musi być wewnątrz 'z', a nie tylko' Popen'. – abarnert

+0

@JFSebastian: Tymczasem dla 'os.devnull', czy rzeczywiście istnieje na każdej platformie, na której' subprocess' istnieje, więc nie ma potrzeby "sprawdzania przed użyciem", czy też po prostu wiesz, że ona również istnieje? na Jythonie i dlatego powinienem przenieść Jython na listę platform, których nie trzeba sprawdzać? – abarnert

6

Z documentation:

Przy ustawieniach domyślnych None, nie nastąpi przekierowanie.

Musisz ustawić stdout do subprocess.PIPE, a następnie zadzwonić .communicate() i po prostu zignorować przechwycony wyjście.

p = subprocess.Popen(['java', '-jar', 'foo.jar'], stdout=subprocess.PIPE) 
p.communicate() 

chociaż podejrzewam, że za pomocą subprocess.call() więcej niż wystarczające dla Twoich potrzeb:

subprocess.call(['java', '-jar', 'foo.jar'], stdout=subprocess.PIPE) 
+1

@sjtaheri: dzięki za korektę, sam ją zgłosiłem. –

+4

Tworzenie i ignorowanie potoku zwykle działa, ale może prowadzić do zablokowania procesu potomnego, jeśli robi zbyt dużo zapisu (i oczywiście może działać w systemie i kończy się niepowodzeniem dla jednego z użytkowników), więc myślę, że tak naprawdę nie jest " t bezpieczne po prostu "zadzwoń" tutaj zamiast "komunikować się". Właśnie dlatego dodano słowo "DEVNULL" - możesz więc po prostu "zadzwonić" i nie martwić się o to. (Cóż, jest tam dla nieco bardziej skomplikowanego przypadku, w którym ustawiasz 'stderr = DEVNULL', ale nie' stdout', i tylko 'check_output' .Ale sam pomysł.) – abarnert

+0

@bahnert: Ah, nie wiedziałem, że został dodany ; po prostu znalazłem to w dokumentacji Pythona 3. –

Powiązane problemy