Czy istnieje wersja subprocess.call
, która może uruchomić polecenie bez drukowania na standardowe wyjście, lub sposób blokowania jego standardowych wiadomości wyjściowych?Czy istnieje cicha wersja podprocesu?
Odpowiedz
Tak. Przekieruj jego stdout
do /dev/null
.
process = subprocess.call(["my", "command"], stdout=open(os.devnull, 'wb'))
'Popen' nie jest odmianą' call'. To zupełnie inna funkcja. – jwg
Masz rację. Jednak Popen i call mają bardzo podobne argumenty, więc te rozwiązania działają dla obu. Przesłałem zmianę. – jhrf
Zauważ, że z Python ver. 3.3 w rzeczywistości istnieje 'subprocess.DEVNULL', który może być użyty zamiast' open (os.devnull, 'wb') '. – EquipDev
Często ten rodzaj pogawędki jest na stderr, więc możesz też chcieć to uciszyć. Oto mój przykład:
from subprocess import call, DEVNULL
return_code = call(args, stderr=DEVNULL, stdout=DEVNULL)
Uwaga:subprocess.DEVNULL
jest dostępny od Pythona 3.3. Jeśli nadal na Pythonie 2:
import os
with open(os.devnull, 'w') as shutup:
return_code = call(args, stdout=shutup, stderr=shutup)
zauważając, że nie ma odpowiedzi na temat używania 'startupinfo', jak pokazano tutaj: http://code.activestate.com/recipes/409002-launching-a-subprocess-without-a-onsole-window/, aby uniknąć migania okna podczas pracy python z konsoli –
python 3 ma teraz 'subprocess.DEVNULL' (ale twoja odpowiedź ma 7 lat) –
@ Jean-FrançoisFabre Było to już wspomniane w komentarzu do zaakceptowanej odpowiedzi. W każdym razie, zredagowałem to teraz, dzięki za sugestię. – wim
subprocess.call
przyjąć również przekierowań stdin/stdout/stderr:
process = subprocess.call(["my", "command"], stdout=open(os.devnull, 'wb'))
[The docs] (http://docs.python.org/2/library/subprocess.html#subprocess.call) wyraźnie mówią "Nie używaj stdout = PIPE lub stderr = PIPE z tą funkcją." – mpen
open() nie zwraca PIPE, PIPE oznacza "subprocess.PIPE", który można odczytać z drugiego końca w programie. Otwarta na 'os.devnull' nie spowoduje problemu, ponieważ nie ma dna w tym pliku z czarną dziurą, bufor nigdy nie zostanie zapełniony. – BOYPT
Ah. To ma sens. Dziękuję Ci! Nie chciałem używać "Popena", ponieważ zwraca on proces zamiast kodu statusu. – mpen
Jest to przepis używam dużo: Call subprocess
i zebrać dane wyjściowe, a gdy polecenie powiedzie się odrzucić dane wyjściowe, ale gdy się nie powiedzie wydrukuj dane wyjściowe.
import subprocess as sp
import sys
if "print" in __builtins__.__dict__:
prn = __builtins__.__dict__["print"]
else:
def prn(*args, **kwargs):
"""
prn(value, ..., sep=' ', end='\\n', file=sys.stdout)
Works just like the print function in Python 3.x but can be used in 2.x.
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
"""
sep = kwargs.get("sep", ' ')
end = kwargs.get("end", '\n')
file = kwargs.get("file", sys.stdout)
s = sep.join(str(x) for x in args) + end
file.write(s)
def rc_run_cmd_basic(lst_cmd, verbose=False, silent=False):
if silent and verbose:
raise ValueError("cannot specify both verbose and silent as true")
p = sp.Popen(lst_cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE)
tup_output = p.communicate()
s_cmd = ' '.join(lst_cmd)
if verbose:
prn()
prn("command: '%s'\n" % s_cmd)
if 0 != p.returncode:
prn()
prn("Command failed with code %d:" % p.returncode)
else:
prn("Command succeeded! code %d" % p.returncode)
if verbose:
prn("Output for: " + s_cmd)
prn(tup_output[0])
prn()
if not silent and 0 != p.returncode:
prn("Error output for: " + s_cmd)
prn(tup_output[1])
prn()
return p.returncode
Używam podprocesów.check_output w takich przypadkach i upuść wartość zwracaną. Możesz dodać komentarz do swojego kodu stwierdzającego, dlaczego używasz check_output zamiast check_call. check_output jest również ładniejszy, gdy wystąpi awaria i jesteś zainteresowany wyjściem błędu. Przykładowy kod poniżej. Dane wyjściowe są widoczne tylko po odkomentowaniu linii drukowania. Jeśli polecenie nie powiedzie się, zostanie zgłoszony wyjątek.
import subprocess
ret = subprocess.check_output(["cat", "/tmp/1"])
#print ret
W jaki sposób upuszczenie wartości zwracanej powoduje, że wyjście nie staje się standardowe? – Emre
subprocess.check_output ma przechwycić dane wyjściowe i je zwrócić. Czy widzisz inne zachowanie? –
Przechwytywanie i ignorowanie utworów, ale powoduje utratę pamięci na przechwyconej wartości, która nigdy nie jest używana. Właściwe odrzucanie danych wyjściowych jest bardziej niezawodne. – tripleee
Ściśle związane http://stackoverflow.com/questions/5495078/how-do-you-discard-subprocess-output-in-python, w szczególności ze względu na wywołanie używa Popen. –
pokrewne: [Jak ukryć wyjście podprocesu w Pythonie 2.7] (http://stackoverflow.com/q/11269575/4279) – jfs