Python Language
Biblioteka podprocesów
Szukaj…
Składnia
- subprocess.call (args, *, stdin = None, stdout = None, stderr = None, shell = False, timeout = None)
- subprocess.Popen (args, bufsize = -1, executable = None, stdin = None, stdout = None, stderr = None, preexec_fn = None, close_fds = True, shell = False, cwd = None, env = None, universal_newlines = False , startupinfo = Brak, createflags = 0, restore_signals = True, start_new_session = False, pass_fds = ())
Parametry
Parametr | Detale |
---|---|
args | Pojedynczy plik wykonywalny lub sekwencja plików wykonywalnych i argumentów - 'ls' , ['ls', '-la'] |
shell | Biegniesz pod skorupą? Domyślna powłoka na /bin/sh w POSIX. |
cwd | Katalog roboczy procesu potomnego. |
Wywoływanie poleceń zewnętrznych
Najprostszym przypadkiem użycia jest użycie funkcji subprocess.call
. Przyjmuje listę jako pierwszy argument. Pierwszą pozycją na liście powinna być aplikacja zewnętrzna, do której chcesz zadzwonić. Pozostałe elementy na liście to argumenty, które zostaną przekazane do tej aplikacji.
subprocess.call([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg'])
W przypadku poleceń powłoki ustaw shell=True
i podaj polecenie jako ciąg zamiast listy.
subprocess.call('echo "Hello, world"', shell=True)
Zauważ, że powyższe dwa polecenia zwracają tylko exit status
podprocesu. Ponadto należy zachować ostrożność przy korzystaniu z shell=True
ponieważ zapewnia ona problemy z bezpieczeństwem (patrz tutaj ).
Jeśli chcesz mieć standardowe wyjście podprocesu, subprocess.call
subprocess.check_output
. Dla bardziej zaawansowanych zastosowań zapoznaj się z tym .
Większa elastyczność dzięki Popen
Korzystanie z subprocess.Popen
daje bardziej szczegółową kontrolę nad uruchomionymi procesami niż subprocess.call
.
Uruchamianie podprocesu
process = subprocess.Popen([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg'])
Podpis Popen
jest bardzo podobny do funkcji call
; jednak Popen
natychmiast powróci, zamiast czekać na zakończenie podprocesu, tak jak robi to call
.
Oczekiwanie na zakończenie podprocesu
process = subprocess.Popen([r'C:\path\to\app.exe', 'arg1', '--flag', 'arg'])
process.wait()
Odczytywanie danych wyjściowych z podprocesu
process = subprocess.Popen([r'C:\path\to\app.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# This will block until process completes
stdout, stderr = process.communicate()
print stdout
print stderr
Interaktywny dostęp do uruchomionych podprocesów
Możesz czytać i pisać na stdin
i stdout
nawet jeśli podproces nie został zakończony. Może to być przydatne podczas automatyzacji funkcji w innym programie.
Zapisywanie do podprocesu
process = subprocess.Popen([r'C:\path\to\app.exe'], stdout = subprocess.PIPE, stdin = subprocess.PIPE)
process.stdin.write('line of input\n') # Write input
line = process.stdout.readline() # Read a line from stdout
# Do logic on line read.
Jeśli jednak potrzebujesz tylko jednego zestawu danych wejściowych i wyjściowych, a nie dynamicznej interakcji, powinieneś użyć communicate()
zamiast bezpośredniego dostępu do stdin
i stdout
.
Odczytywanie strumienia z podprocesu
Jeśli chcesz wyświetlać dane wyjściowe podprocesu linia po linii, możesz użyć następującego fragmentu kodu:
process = subprocess.Popen(<your_command>, stdout=subprocess.PIPE)
while process.poll() is None:
output_line = process.stdout.readline()
jeśli wyjście komendy nie ma znaku EOL, powyższy fragment kodu nie działa. Następnie możesz odczytać wynikowy znak po znaku w następujący sposób:
process = subprocess.Popen(<your_command>, stdout=subprocess.PIPE)
while process.poll() is None:
output_line = process.stdout.read(1)
1
podano jako argument do read
metody nakazuje czytać czytać 1 znak w czasie. Możesz określić, aby odczytać tyle znaków, ile chcesz, używając innej liczby. Liczba ujemna lub 0 każe read
aby czytać jako pojedynczy ciąg znaków, aż napotkamy EOF ( patrz tutaj ).
W obu powyższych fragmentach process.poll()
ma wartość None
dopóki podproces nie zakończy się. Służy to do wyjścia z pętli, gdy nie będzie już więcej danych wyjściowych do odczytu.
Tę samą procedurę można zastosować do stderr
podprocesu.
Jak utworzyć argument listy poleceń
Metoda podprocesu, która pozwala na uruchamianie poleceń, wymaga polecenia w postaci listy (przynajmniej przy użyciu shell_mode=True
).
Zasady tworzenia listy nie zawsze są łatwe do przestrzegania, szczególnie w przypadku złożonych poleceń. Na szczęście istnieje bardzo pomocne narzędzie, które pozwala to zrobić: shlex
. Najłatwiejszym sposobem utworzenia listy używanej jako polecenie jest:
import shlex
cmd_to_subprocess = shlex.split(command_used_in_the_shell)
Prosty przykład:
import shlex
shlex.split('ls --color -l -t -r')
out: ['ls', '--color', '-l', '-t', '-r']