Автор оригинала: Doug Hellmann.
Цель:
Запускайте дополнительные процессы и общайтесь с ними.
Модуль subprocess
поддерживает три API для работы с процессами. Функция run ()
, добавленная в Python 3.5, представляет собой высокоуровневый API для запуска процесса и, при необходимости, сбора его вывода. Функции call ()
, check_call ()
и check_output ()
– это бывший высокоуровневый API, перенесенный из Python 2. Они все еще поддерживаются и широко используются в существующих программах. Класс Popen
– это низкоуровневый API, используемый для создания других API и полезный для более сложных взаимодействий процессов. Конструктор для Popen
принимает аргументы для настройки нового процесса, чтобы родитель мог взаимодействовать с ним по каналам. Он обеспечивает все функции других модулей и функций, которые он заменяет, и многое другое. API единообразен для всех видов использования, и многие из необходимых дополнительных шагов (таких как закрытие дополнительных файловых дескрипторов и обеспечение закрытия каналов) «встроены», а не обрабатываются кодом приложения отдельно.
Модуль subprocess
предназначен для замены таких функций, как os.system ()
, os.spawnv ()
, вариантов popen ()
в модулях os и popen2
, а также в модуле commands ()
. Чтобы упростить сравнение subprocess
с этими другими модулями, многие примеры в этом разделе воссоздают те, которые использовались для os и popen2
.
Примечание
API для работы в Unix и Windows примерно одинаков, но основная реализация отличается из-за разницы в моделях процессов в операционных системах. Все показанные здесь примеры были протестированы в Mac OS X. Поведение в ОС, отличной от Unix, может отличаться.
Запуск внешней команды
Чтобы запустить внешнюю команду, не взаимодействуя с ней так же, как os.system ()
, используйте функцию run ()
.
subprocess_os_system.py
import subprocess completed subprocess.run(['ls', '-1']) print('returncode:', completed.returncode)
Аргументы командной строки передаются в виде списка строк, что позволяет избежать необходимости экранирования кавычек или других специальных символов, которые могут быть интерпретированы оболочкой. run ()
возвращает экземпляр CompletedProcess
с информацией о процессе, такой как код выхода и выходные данные.
$ python3 subprocess_os_system.py index.rst interaction.py repeater.py signal_child.py signal_parent.py subprocess_check_output_error_trap_output.py subprocess_os_system.py subprocess_pipes.py subprocess_popen2.py subprocess_popen3.py subprocess_popen4.py subprocess_popen_read.py subprocess_popen_write.py subprocess_run_check.py subprocess_run_output.py subprocess_run_output_error.py subprocess_run_output_error_suppress.py subprocess_run_output_error_trap.py subprocess_shell_variables.py subprocess_signal_parent_shell.py subprocess_signal_setpgrp.py returncode: 0
Установка аргумента shell
в истинное значение приводит к тому, что subprocess
порождает промежуточный процесс оболочки, который затем запускает команду. По умолчанию команда запускается напрямую.
subprocess_shell_variables.py
import subprocess completed subprocess.run('echo $HOME', shellTrue) print('returncode:', completed.returncode)
Использование промежуточной оболочки означает, что переменные, шаблоны глобусов и другие специальные функции оболочки в командной строке обрабатываются до запуска команды.
$ python3 subprocess_shell_variables.py /Users/dhellmann returncode: 0
Примечание
Использование run ()
без передачи
эквивалентно использованию call ()
, который возвращает только код выхода из процесса.
Обработка ошибок
Атрибут returncode
для CompletedProcess
– это код выхода программы. Вызывающий отвечает за его интерпретацию для обнаружения ошибок. Если аргумент check
для run ()
имеет значение True
, проверяется код выхода, и если он указывает, что произошла ошибка, то CalledProcessError
возникает исключение.
subprocess_run_check.py
import subprocess try: subprocess.run(['false'], checkTrue) except subprocess.CalledProcessError as err: print('ERROR:', err)
Команда false
всегда завершается с ненулевым кодом состояния, который run ()
интерпретирует как ошибку.
$ python3 subprocess_run_check.py ERROR: Command '['false']' returned non-zero exit status 1
Примечание
Передача
в run ()
делает его эквивалентным использованию check_call ()
.
Захват вывода
Стандартные каналы ввода и вывода для процесса, запущенного run ()
, привязаны к родительскому вводу и выводу. Это означает, что вызывающая программа не может захватить вывод команды. Передайте PIPE
для аргументов stdout
и stderr
, чтобы захватить вывод для последующей обработки.
subprocess_run_output.py
import subprocess completed subprocess.run( ['ls', '-1'], stdoutsubprocess.PIPE, ) print('returncode:', completed.returncode) print('Have {} bytes in stdout:\n{}'.format( len(completed.stdout), completed.stdout.decode('utf-8')) )
Команда ls -1
выполняется успешно, поэтому текст, который она выводит на стандартный вывод, фиксируется и возвращается.
$ python3 subprocess_run_output.py returncode: 0 Have 522 bytes in stdout: index.rst interaction.py repeater.py signal_child.py signal_parent.py subprocess_check_output_error_trap_output.py subprocess_os_system.py subprocess_pipes.py subprocess_popen2.py subprocess_popen3.py subprocess_popen4.py subprocess_popen_read.py subprocess_popen_write.py subprocess_run_check.py subprocess_run_output.py subprocess_run_output_error.py subprocess_run_output_error_suppress.py subprocess_run_output_error_trap.py subprocess_shell_variables.py subprocess_signal_parent_shell.py subprocess_signal_setpgrp.py
Примечание
Передача
и установка для stdout
значения PIPE
эквивалентны использованию check_output ()
.
В следующем примере выполняется серия команд во вспомогательной оболочке. Сообщения отправляются на стандартный вывод и стандартную ошибку до выхода команд с кодом ошибки.
subprocess_run_output_error.py
import subprocess try: completed subprocess.run( 'echo to stdout; echo to stderr 1>&2; exit 1', checkTrue, shellTrue, stdoutsubprocess.PIPE, ) except subprocess.CalledProcessError as err: print('ERROR:', err) else: print('returncode:', completed.returncode) print('Have {} bytes in stdout: {!r}'.format( len(completed.stdout), completed.stdout.decode('utf-8')) )
Сообщение стандартной ошибки выводится на консоль, но сообщение стандартного вывода скрыто.
$ python3 subprocess_run_output_error.py to stderr ERROR: Command 'echo to stdout; echo to stderr 1>&2; exit 1' returned non-zero exit status 1
Чтобы сообщения об ошибках от команд, выполняемых через run ()
, не записывались в консоль, установите для параметра stderr
константу PIPE
.
subprocess_run_output_error_trap.py
import subprocess try: completed subprocess.run( 'echo to stdout; echo to stderr 1>&2; exit 1', shellTrue, stdoutsubprocess.PIPE, stderrsubprocess.PIPE, ) except subprocess.CalledProcessError as err: print('ERROR:', err) else: print('returncode:', completed.returncode) print('Have {} bytes in stdout: {!r}'.format( len(completed.stdout), completed.stdout.decode('utf-8')) ) print('Have {} bytes in stderr: {!r}'.format( len(completed.stderr), completed.stderr.decode('utf-8')) )
В этом примере не устанавливается
, поэтому вывод команды фиксируется и печатается.
$ python3 subprocess_run_output_error_trap.py returncode: 1 Have 10 bytes in stdout: 'to stdout\n' Have 10 bytes in stderr: 'to stderr\n'
Чтобы записывать сообщения об ошибках при использовании check_output ()
, установите для stderr
значение STDOUT
, и сообщения будут объединены с остальной частью вывода из команда.
subprocess_check_output_error_trap_output.py
import subprocess try: output subprocess.check_output( 'echo to stdout; echo to stderr 1>&2', shellTrue, stderrsubprocess.STDOUT, ) except subprocess.CalledProcessError as err: print('ERROR:', err) else: print('Have {} bytes in output: {!r}'.format( len(output), output.decode('utf-8')) )
Порядок вывода может варьироваться в зависимости от того, как буферизация применяется к стандартному потоку вывода и сколько данных печатается.
$ python3 subprocess_check_output_error_trap_output.py Have 20 bytes in output: 'to stdout\nto stderr\n'
Подавление вывода
В случаях, когда вывод не должен отображаться или фиксироваться, используйте DEVNULL
для подавления потока вывода. В этом примере подавляются как стандартный вывод, так и потоки ошибок.
subprocess_run_output_error_suppress.py
import subprocess try: completed subprocess.run( 'echo to stdout; echo to stderr 1>&2; exit 1', shellTrue, stdoutsubprocess.DEVNULL, stderrsubprocess.DEVNULL, ) except subprocess.CalledProcessError as err: print('ERROR:', err) else: print('returncode:', completed.returncode) print('stdout is {!r}'.format(completed.stdout)) print('stderr is {!r}'.format(completed.stderr))
Имя DEVNULL
происходит от файла специального устройства Unix, /dev/null
, который отвечает концом файла при открытии для чтения и принимает, но игнорирует любой объем ввода. при написании.
$ python3 subprocess_run_output_error_suppress.py returncode: 1 stdout is None stderr is None
Непосредственная работа с трубами
Функции run ()
, call ()
, check_call ()
и check_output ()
являются оболочками вокруг Popen
класс. Прямое использование Popen
дает больший контроль над тем, как выполняется команда, и как обрабатываются ее входные и выходные потоки. Например, передавая разные аргументы для stdin
, stdout
и stderr
, можно имитировать варианты os.popen ( )
.
Одностороннее общение с процессом
Чтобы запустить процесс и прочитать весь его вывод, установите для значения stdout
значение PIPE
и вызовите communication ()
.
subprocess_popen_read.py
import subprocess print('read:') proc subprocess.Popen( ['echo', '"to stdout"'], stdoutsubprocess.PIPE, ) stdout_value proc.communicate()[0].decode('utf-8') print('stdout:', repr(stdout_value))
Это похоже на то, как работает popen ()
, за исключением того, что чтение управляется внутренне экземпляром Popen
.
$ python3 subprocess_popen_read.py read: stdout: '"to stdout"\n'
Чтобы настроить канал, позволяющий вызывающей программе записывать в него данные, установите для stdin
значение PIPE
.
subprocess_popen_write.py
import subprocess print('write:') proc subprocess.Popen( ['cat', '-'], stdinsubprocess.PIPE, ) proc.communicate('stdin: to stdin\n'.encode('utf-8'))
Чтобы отправить данные в стандартный входной канал процесса один раз, передайте данные в communication ()
. Это похоже на использование popen ()
с режимом 'w'
.
$ python3 -u subprocess_popen_write.py write: stdin: to stdin
Двунаправленная коммуникация с процессом
Чтобы настроить экземпляр Popen
для одновременного чтения и записи, используйте комбинацию предыдущих методов.
subprocess_popen2.py
import subprocess print('popen2:') proc subprocess.Popen( ['cat', '-'], stdinsubprocess.PIPE, stdoutsubprocess.PIPE, ) msg 'through stdin to stdout'.encode('utf-8') stdout_value proc.communicate(msg)[0].decode('utf-8') print('pass through:', repr(stdout_value))
Это настраивает канал для имитации popen2 ()
.
$ python3 -u subprocess_popen2.py popen2: pass through: 'through stdin to stdout'
Захват вывода ошибок
Также возможно наблюдать за обоими потоками для stdout
и stderr
, как и для popen3 ()
.
subprocess_popen3.py
import subprocess print('popen3:') proc subprocess.Popen( 'cat -; echo "to stderr" 1>&2', shellTrue, stdinsubprocess.PIPE, stdoutsubprocess.PIPE, stderrsubprocess.PIPE, ) msg 'through stdin to stdout'.encode('utf-8') stdout_value, stderr_value proc.communicate(msg) print('pass through:', repr(stdout_value.decode('utf-8'))) print('stderr :', repr(stderr_value.decode('utf-8')))
Чтение из stderr
работает так же, как с stdout
. Передача PIPE
указывает Popen
подключиться к каналу, а communication ()
считывает все данные из него перед возвратом.
$ python3 -u subprocess_popen3.py popen3: pass through: 'through stdin to stdout' stderr : 'to stderr\n'
Комбинирование обычного вывода и вывода ошибок
Чтобы направить вывод ошибки из процесса в его стандартный канал вывода, используйте STDOUT
для stderr
вместо PIPE
.
subprocess_popen4.py
import subprocess print('popen4:') proc subprocess.Popen( 'cat -; echo "to stderr" 1>&2', shellTrue, stdinsubprocess.PIPE, stdoutsubprocess.PIPE, stderrsubprocess.STDOUT, ) msg 'through stdin to stdout\n'.encode('utf-8') stdout_value, stderr_value proc.communicate(msg) print('combined output:', repr(stdout_value.decode('utf-8'))) print('stderr value :', repr(stderr_value))
Такое объединение вывода аналогично тому, как работает popen4 ()
.
$ python3 -u subprocess_popen4.py popen4: combined output: 'through stdin to stdout\nto stderr\n' stderr value : None
Соединение отрезков трубы
Несколько команд можно объединить в конвейер , аналогично тому, как работает оболочка Unix, путем создания отдельных экземпляров Popen
и объединения их входных и выходных данных вместе. Атрибут stdout
одного экземпляра Popen
используется в качестве аргумента stdin
для следующего в конвейере вместо константы PIPE . Вывод считывается из дескриптора
stdout
для последней команды в конвейере.
subprocess_pipes.py
import subprocess cat subprocess.Popen( ['cat', 'index.rst'], stdoutsubprocess.PIPE, ) grep subprocess.Popen( ['grep', '.. literalinclude::'], stdincat.stdout, stdoutsubprocess.PIPE, ) cut subprocess.Popen( ['cut', '-f', '3', '-d:'], stdingrep.stdout, stdoutsubprocess.PIPE, ) end_of_pipe cut.stdout print('Included files:') for line in end_of_pipe: print(line.decode('utf-8').strip())
В примере воспроизводится командная строка:
$ cat index.rst | grep ".. literalinclude" | cut -f 3 -d:
Конвейер считывает исходный файл reStructuredText для этого раздела и находит все строки, содержащие другие файлы, а затем печатает имена включаемых файлов.
$ python3 -u subprocess_pipes.py Included files: subprocess_os_system.py subprocess_shell_variables.py subprocess_run_check.py subprocess_run_output.py subprocess_run_output_error.py subprocess_run_output_error_trap.py subprocess_check_output_error_trap_output.py subprocess_run_output_error_suppress.py subprocess_popen_read.py subprocess_popen_write.py subprocess_popen2.py subprocess_popen3.py subprocess_popen4.py subprocess_pipes.py repeater.py interaction.py signal_child.py signal_parent.py subprocess_signal_parent_shell.py subprocess_signal_setpgrp.py
Взаимодействие с другой командой
Все предыдущие примеры предполагают ограниченное количество взаимодействий. Метод communications ()
считывает весь вывод и ожидает завершения дочернего процесса перед возвратом. Также можно записывать и считывать отдельные дескрипторы каналов, используемые экземпляром Popen
, постепенно по мере выполнения программы. Простая программа эха, которая считывает со стандартного ввода и записывает в стандартный вывод, иллюстрирует эту технику.
Сценарий Repeater.py
используется в качестве дочернего процесса в следующем примере. Он читает из stdin
и записывает значения в stdout
, по одной строке за раз, пока больше не будет ввода. Он также записывает сообщение в stderr
при запуске и останове, показывая время жизни дочернего процесса.
repeater.py
import sys sys.stderr.write('repeater.py: starting\n') sys.stderr.flush() while True: next_line sys.stdin.readline() sys.stderr.flush() if not next_line: break sys.stdout.write(next_line) sys.stdout.flush() sys.stderr.write('repeater.py: exiting\n') sys.stderr.flush()
В следующем примере взаимодействия по-разному используются дескрипторы файлов stdin
и stdout
, принадлежащие экземпляру Popen
. В первом примере последовательность из пяти чисел записывается в stdin
процесса, и после каждой записи считывается следующая строка вывода. Во втором примере записываются те же пять чисел, но вывод считывается сразу с помощью communication ()
.
interaction.py
import io import subprocess print('One line at a time:') proc subprocess.Popen( 'python3 repeater.py', shellTrue, stdinsubprocess.PIPE, stdoutsubprocess.PIPE, ) stdin io.TextIOWrapper( proc.stdin, encoding'utf-8', line_bufferingTrue, # send data on newline ) stdout io.TextIOWrapper( proc.stdout, encoding'utf-8', ) for i in range(5): line '{}\n'.format(i) stdin.write(line) output stdout.readline() print(output.rstrip()) remainder proc.communicate()[0].decode('utf-8') print(remainder) print() print('All output at once:') proc subprocess.Popen( 'python3 repeater.py', shellTrue, stdinsubprocess.PIPE, stdoutsubprocess.PIPE, ) stdin io.TextIOWrapper( proc.stdin, encoding'utf-8', ) for i in range(5): line '{}\n'.format(i) stdin.write(line) stdin.flush() output proc.communicate()[0].decode('utf-8') print(output)
Строки "Repeater.py: exiting"
находятся в разных точках вывода для каждого стиля цикла.
$ python3 -u interaction.py One line at a time: repeater.py: starting 0 1 2 3 4 repeater.py: exiting All output at once: repeater.py: starting repeater.py: exiting 0 1 2 3 4
Сигнализация между процессами
Примеры управления процессами для модуля os включают демонстрацию передачи сигналов между процессами с помощью os.fork ()
и os.kill ()
. Поскольку каждый экземпляр Popen
предоставляет атрибут pid с идентификатором дочернего процесса, можно сделать что-то подобное с subprocess
. В следующем примере объединены два скрипта. Этот дочерний процесс устанавливает обработчик сигнала для сигнала USR
.
signal_child.py
import os import signal import time import sys pid os.getpid() received False def signal_usr1(signum, frame): "Callback invoked when a signal is received" global received received True print('CHILD {:>6}: Received USR1'.format(pid)) sys.stdout.flush() print('CHILD {:>6}: Setting up signal handler'.format(pid)) sys.stdout.flush() signal.signal(signal.SIGUSR1, signal_usr1) print('CHILD {:>6}: Pausing to wait for signal'.format(pid)) sys.stdout.flush() time.sleep(3) if not received: print('CHILD {:>6}: Never received signal'.format(pid))
Этот сценарий запускается как родительский процесс. Он запускает signal_child.py
, затем отправляет сигнал USR1
.
signal_parent.py
import os import signal import subprocess import time import sys proc subprocess.Popen(['python3', 'signal_child.py']) print('PARENT : Pausing before sending signal...') sys.stdout.flush() time.sleep(1) print('PARENT : Signaling child') sys.stdout.flush() os.kill(proc.pid, signal.SIGUSR1)
Результат:
$ python3 signal_parent.py PARENT : Pausing before sending signal... CHILD 26976: Setting up signal handler CHILD 26976: Pausing to wait for signal PARENT : Signaling child CHILD 26976: Received USR1
Группы процессов/сеансы
Если процесс, созданный Popen
, порождает подпроцессы, эти дочерние элементы не будут получать никаких сигналов, отправленных родителю. Это означает, что при использовании аргумента shell
для Popen
будет трудно вызвать завершение команды, запущенной в оболочке, отправив SIGINT
или SIGTERM
.
subprocess_signal_parent_shell.py
import os import signal import subprocess import tempfile import time import sys script '''#!/bin/sh echo "Shell script in process $$" set -x python3 signal_child.py ''' script_file tempfile.NamedTemporaryFile('wt') script_file.write(script) script_file.flush() proc subprocess.Popen(['sh', script_file.name]) print('PARENT : Pausing before signaling {}...'.format( proc.pid)) sys.stdout.flush() time.sleep(1) print('PARENT : Signaling child {}'.format(proc.pid)) sys.stdout.flush() os.kill(proc.pid, signal.SIGUSR1) time.sleep(3)
Pid, используемый для отправки сигнала, не соответствует pid дочернего элемента сценария оболочки, ожидающего сигнала, потому что в этом примере взаимодействуют три отдельных процесса:
- П
- р
- о
- г
- р
- а
- м
- м
- а
- <
- c
- o
- d
- e
- >
- s
- u
- b
- p
- r
- o
- c
- e
- s
- s
- _
- s
- i
- g
- n
- a
- l
- _
- p
- a
- r
- e
- n
- t
- _
- s
- h
- e
- l
- l
- .
- p
- y
- <
- /
- c
- o
- d
- e
- >
- П
- р
- о
- ц
- е
- с
- с
- о
- б
- о
- л
- о
- ч
- к
- и
- ,
- з
- а
- п
- у
- с
- к
- а
- ю
- щ
- и
- й
- с
- к
- р
- и
- п
- т
- ,
- с
- о
- з
- д
- а
- н
- н
- ы
- й
- о
- с
- н
- о
- в
- н
- о
- й
- п
- р
- о
- г
- р
- а
- м
- м
- о
- й
- P
- y
- t
- h
- o
- n
- П
- р
- о
- г
- р
- а
- м
- м
- а
- <
- c
- o
- d
- e
- >
- s
- i
- g
- n
- a
- l
- _
- c
- h
- i
- l
- d
- .
- p
- y
- <
- /
- c
- o
- d
- e
- >
$ python3 subprocess_signal_parent_shell.py PARENT : Pausing before signaling 26984... Shell script in process 26984 + python3 signal_child.py CHILD 26985: Setting up signal handler CHILD 26985: Pausing to wait for signal PARENT : Signaling child 26984 CHILD 26985: Never received signal
Чтобы отправлять сигналы потомкам, не зная их идентификатора процесса, используйте группу процессов , чтобы связать потомков, чтобы они могли сигнализировать вместе. Группа процессов создается с помощью os.setpgrp ()
, который устанавливает идентификатор группы процессов равным идентификатору текущего процесса. Все дочерние процессы наследуют свою группу процессов от своего родителя, и, поскольку она должна быть установлена только в оболочке, созданной Popen
и его потомками, os.setpgrp ()
не должен быть вызывается в том же процессе, в котором создается Popen
. Вместо этого функция передается в Popen
как аргумент preexec_fn
, поэтому она запускается после fork ()
внутри нового процесса, прежде чем он использует exec ()
для запуска оболочки. Чтобы сигнализировать всей группе процессов, используйте os.killpg ()
со значением pid
из экземпляра Popen
.
subprocess_signal_setpgrp.py
import os import signal import subprocess import tempfile import time import sys def show_setting_prgrp(): print('Calling os.setpgrp() from {}'.format(os.getpid())) os.setpgrp() print('Process group is now {}'.format(os.getpgrp())) sys.stdout.flush() script '''#!/bin/sh echo "Shell script in process $$" set -x python3 signal_child.py ''' script_file tempfile.NamedTemporaryFile('wt') script_file.write(script) script_file.flush() proc subprocess.Popen( ['sh', script_file.name], preexec_fnshow_setting_prgrp, ) print('PARENT : Pausing before signaling {}...'.format( proc.pid)) sys.stdout.flush() time.sleep(1) print('PARENT : Signaling process group {}'.format( proc.pid)) sys.stdout.flush() os.killpg(proc.pid, signal.SIGUSR1) time.sleep(3)
Последовательность событий такова.
- Р
- о
- д
- и
- т
- е
- л
- ь
- с
- к
- а
- я
- п
- р
- о
- г
- р
- а
- м
- м
- а
- с
- о
- з
- д
- а
- е
- т
- э
- к
- з
- е
- м
- п
- л
- я
- р
- <
- c
- o
- d
- e
- >
- P
- o
- p
- e
- n
- <
- /
- c
- o
- d
- e
- >
- .
- Э
- к
- з
- е
- м
- п
- л
- я
- р
- <
- c
- o
- d
- e
- >
- P
- o
- p
- e
- n
- <
- /
- c
- o
- d
- e
- >
- в
- ы
- з
- ы
- в
- а
- е
- т
- н
- о
- в
- ы
- й
- п
- р
- о
- ц
- е
- с
- с
- .
- Н
- о
- в
- ы
- й
- п
- р
- о
- ц
- е
- с
- с
- з
- а
- п
- у
- с
- к
- а
- е
- т
- <
- c
- o
- d
- e
- >
- o
- s
- .
- s
- e
- t
- p
- g
- r
- p
- (
- )
- <
- /
- c
- o
- d
- e
- >
- .
- Н
- о
- в
- ы
- й
- п
- р
- о
- ц
- е
- с
- с
- з
- а
- п
- у
- с
- к
- а
- е
- т
- <
- c
- o
- d
- e
- >
- e
- x
- e
- c
- (
- )
- <
- /
- c
- o
- d
- e
- >
- д
- л
- я
- з
- а
- п
- у
- с
- к
- а
- о
- б
- о
- л
- о
- ч
- к
- и
- .
- О
- б
- о
- л
- о
- ч
- к
- а
- з
- а
- п
- у
- с
- к
- а
- е
- т
- с
- ц
- е
- н
- а
- р
- и
- й
- о
- б
- о
- л
- о
- ч
- к
- и
- .
- С
- ц
- е
- н
- а
- р
- и
- й
- о
- б
- о
- л
- о
- ч
- к
- и
- с
- н
- о
- в
- а
- р
- а
- з
- в
- е
- т
- в
- л
- я
- е
- т
- с
- я
- ,
- и
- э
- т
- о
- т
- п
- р
- о
- ц
- е
- с
- с
- з
- а
- п
- у
- с
- к
- а
- е
- т
- P
- y
- t
- h
- o
- n
- .
- P
- y
- t
- h
- o
- n
- з
- а
- п
- у
- с
- к
- а
- е
- т
- <
- c
- o
- d
- e
- >
- s
- i
- g
- n
- a
- l
- _
- c
- h
- i
- l
- d
- .
- p
- y
- <
- /
- c
- o
- d
- e
- >
- .
- Р
- о
- д
- и
- т
- е
- л
- ь
- с
- к
- а
- я
- п
- р
- о
- г
- р
- а
- м
- м
- а
- с
- и
- г
- н
- а
- л
- и
- з
- и
- р
- у
- е
- т
- г
- р
- у
- п
- п
- е
- п
- р
- о
- ц
- е
- с
- с
- о
- в
- ,
- и
- с
- п
- о
- л
- ь
- з
- у
- я
- p
- i
- d
- о
- б
- о
- л
- о
- ч
- к
- и
- .
- С
- и
- г
- н
- а
- л
- п
- о
- л
- у
- ч
- а
- ю
- т
- п
- р
- о
- ц
- е
- с
- с
- ы
- о
- б
- о
- л
- о
- ч
- к
- и
- и
- P
- y
- t
- h
- o
- n
- .
- О
- б
- о
- л
- о
- ч
- к
- а
- и
- г
- н
- о
- р
- и
- р
- у
- е
- т
- с
- и
- г
- н
- а
- л
- .
- П
- р
- о
- ц
- е
- с
- с
- P
- y
- t
- h
- o
- n
- ,
- в
- ы
- п
- о
- л
- н
- я
- ю
- щ
- и
- й
- <
- c
- o
- d
- e
- >
- s
- i
- g
- n
- a
- l
- _
- c
- h
- i
- l
- d
- .
- p
- y
- <
- /
- c
- o
- d
- e
- >
- ,
- в
- ы
- з
- ы
- в
- а
- е
- т
- о
- б
- р
- а
- б
- о
- т
- ч
- и
- к
- с
- и
- г
- н
- а
- л
- а
- .
$ python3 subprocess_signal_setpgrp.py Calling os.setpgrp() from 75636 Process group is now 75636 PARENT : Pausing before signaling 75636... Shell script in process 75636 + python3 signal_child.py CHILD 75637: Setting up signal handler CHILD 75637: Pausing to wait for signal PARENT : Signaling process group 75636 CHILD 75637: Received USR1
Смотрите также
- стандартная библиотечная документация для подпроцесса
- os – хотя
subprocess
заменяет многие из них, функции для работы с процессами, найденные в модуле os, по-прежнему широко используются в существующем коде. - Сигналы и группы процессов UNIX – хорошее описание сигнализации и как работают группы процессов.
- signal – дополнительные сведения об использовании модуля
signal
. - Расширенное программирование в среде UNIX (R) – охватывает работу с несколькими процессами, такими как обработка сигналов, закрытие дублированных файловых дескрипторов и т. Д.
pipe
– шаблоны конвейера команд оболочки Unix в стандартной библиотеке.