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']


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow