subprocess
— Управление подпроцессами¶
Модуль subprocess
позволяет создавать новые процессы,
подключаться к их стандартным потокам ввода/вывода/ошибок и получать их
коды возврата. Модуль предназначен для замены нескольких старых модулей и функций:
os.system
os.spawn*
Информацию о том, как модуль subprocess
можно использовать для замены
данных модулей и функций, можно найти в следующих разделах.
См.также
PEP 324 — PEP предлагающий модуль subprocess
Использование модуля subprocess
¶
Рекомендуемый подход к вызову подпроцессов — использовать функцию run()
для всех возможных вариантов использования. Для более сложных случаев
можно напрямую использовать базовый интерфейс Popen
.
Функция run()
была добавлена в Python 3.5; если вам нужно сохранить
совместимость со старыми версиями, см. раздел Старый высокоуровневый API.
-
subprocess.
run
(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None, **other_popen_kwargs)¶ Выполнить команду, описанную в args. Дождаться завершения команды, затем вернуть экземпляр
CompletedProcess
.Аргументы, показанные выше, являются просто наиболее распространенными, описанными ниже в Часто используемые аргументы (отсюда и использование только ключевой нотации в сокращенной сигнатуре). Полная сигнатура функции во многом такая же, как у конструктора
Popen
— большинство аргументов функции передаются через данный интерфейс. (timeout, input, check и capture_output не являются.)Если capture_output истинно, будут захвачены stdout и stderr. При использовании внутреннего объекта
Popen
автоматически создаётся сstdout=PIPE
иstderr=PIPE
. Аргументы stdout и stderr нельзя указывать одновременно с capture_output. Если вы хотите захватить и объединить оба потока в один, используйтеstdout=PIPE
иstderr=STDOUT
вместо capture_output.Аргумент timeout передаётся в
Popen.communicate()
. Если таймаут истечёт, дочерний процесс будет убит и будет ждать. ИсключениеTimeoutExpired
будет повторно вызвано после завершения дочернего процесса.Аргумент input передаётся в
Popen.communicate()
и, следовательно, в stdin подпроцесса. Если используется, это последовательность байтов, или строка (если указано encoding или errors), или истинный text. При использовании внутренний объектPopen
автоматически создаётся сstdin=PIPE
, и аргумент stdin также не может использоваться.Если check истинно, и процесс завершается с ненулевым кодом выхода, возникает исключение
CalledProcessError
. Атрибуты этого исключения содержат аргументы, код выхода и stdout и stderr, если они были захвачены.Если указаны encoding или errors или text истинно, файловые объекты для stdin, stdout и stderr открываются в текстовом режиме с использованием указанных encoding и errors или
io.TextIOWrapper
по умолчанию. Аргумент universal_newlines эквивалентен text и предоставляется для обратной совместимости. По умолчанию файловые объекты открываются в двоичном режиме.Если env не
None
, то должно использоваться отображение, которое определяет переменные среды для нового процесса; они используются вместо поведения по умолчанию при наследовании среды текущего процесса. Она передается напрямую вPopen
.Примеры:
>>> subprocess.run(["ls", "-l"]) # не захватывает вывод CompletedProcess(args=['ls', '-l'], returncode=0) >>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 >>> subprocess.run(["ls", "-l", "/dev/null"], capture_output=True) CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n', stderr=b'')
Добавлено в версии 3.5.
Изменено в версии 3.6: Добавлены параметры encoding и errors
Изменено в версии 3.7: Добавлен параметр text, как более понятный псевдоним universal_newlines. Добавлен параметр capture_output.
-
class
subprocess.
CompletedProcess
¶ Возвращаемое значение из
run()
, представляющее завершённый процесс.-
args
¶ Аргументы, используемые для запуска процесса. Может быть списком или строкой.
-
returncode
¶ Статус выхода из дочернего процесса. Как правило, статус выхода 0 указывает на успешное выполнение.
Отрицательное значение
-N
указывает, что дочерний был прерван сигналомN
(только POSIX).
-
stdout
¶ Захваченный стандартный вывод дочернего процесса. Последовательность байтов или строка, если
run()
была вызвана с encoding, errors или text=True.None
, если стандартный вывод не был захвачен.Если вы запустили процесс с
stderr=subprocess.STDOUT
, stdout и stderr будут объединены в этом атрибуте, аstderr
будетNone
.
-
stderr
¶ Захваченный stderr из дочернего процесса. Последовательность байтов или строка, если
run()
был вызван с кодировкой, ошибками или текстом = True.None
, если stderr не был захвачен.
-
check_returncode
()¶ Если
returncode
не равно нулю, вызываетCalledProcessError
.
Добавлено в версии 3.5.
-
-
subprocess.
DEVNULL
¶ Специальное значение, которое может использоваться в качестве аргумента stdin, stdout или stderr для
Popen
и указывает, что будет использоваться специальный файлos.devnull
.Добавлено в версии 3.3.
-
subprocess.
PIPE
¶ Специальное значение, которое может использоваться в качестве аргумента stdin, stdout или stderr для
Popen
и указывает, что должен быть открыт конвейер (pipe) к стандартному потоку. Наиболее полезно сPopen.communicate()
.
-
subprocess.
STDOUT
¶ Специальное значение, которое может использоваться в качестве аргумента stderr для
Popen
и указывает, что стандартная ошибка должна передаваться в тот же дескриптор, что и стандартный вывод.
-
exception
subprocess.
SubprocessError
¶ Базовый класс для всех остальных исключений из данного модуля.
Добавлено в версии 3.3.
-
exception
subprocess.
TimeoutExpired
¶ Подкласс
SubprocessError
, вызываемый, когда истекает таймаут во время ожидания дочернего процесса.-
cmd
¶ Команда, которая использовалась для создания дочернего процесса.
-
timeout
¶ Тайм-аут в секундах.
-
output
¶ Вывод дочернего процесса, если он был захвачен
run()
илиcheck_output()
. В противном случаеNone
.
-
stderr
¶ Выходные данные Stderr дочернего процесса, если они были захвачены
run()
. В противном случаеNone
.
Добавлено в версии 3.3.
Изменено в версии 3.5: Добавлены атрибуты stdout и stderr
-
-
exception
subprocess.
CalledProcessError
¶ Подкласс
SubprocessError
, возникающий, когда процесс, выполняемыйcheck_call()
илиcheck_output()
, возвращает ненулевой статус выхода.-
returncode
¶ Статус выхода из дочернего процесса. Если процесс завершился из-за сигнала, это будет отрицательный номер сигнала.
-
cmd
¶ Команда, которая использовалась для создания дочернего процесса.
-
output
¶ Вывод дочернего процесса, если он был захвачен
run()
илиcheck_output()
. В противном случаеNone
.
-
stderr
¶ Выходные данные stderr дочернего процесса, если они были захвачены
run()
. В противном случаеNone
.
Изменено в версии 3.5: Добавлены атрибуты stdout и stderr
-
Часто используемые аргументы¶
Для поддержки широкого спектра вариантов использования конструктор
Popen
(и вспомогательные функции) принимает большое количество
необязательных аргументов. В большинстве типичных случаев использования для
многих из этих аргументов можно безопасно оставить значения по умолчанию.
Наиболее часто используются следующие аргументы:
args требуется для всех вызовов и должен быть строкой или последовательностью аргументов программы. Как правило, предпочтительнее указывать последовательность аргументов, поскольку она позволяет модулю позаботиться о любом необходимом экранировании и закавычивании аргументов (например, разрешить пробелы в именах файлов). При передаче одной строки либо shell должно быть
True
(см. ниже), либо строка должна просто называть программу, которая будет выполняться, без указания каких-либо аргументов.stdin, stdout и stderr определяют обработчики стандартного ввода, стандартного вывода и стандартного файла ошибок исполняемой программы соответственно. Допустимые значения:
PIPE
,DEVNULL
, существующий дескриптор файла (положительное целое число), существующий файловый объект иNone
.PIPE
указывает, что необходимо создать новый конвейер для дочернего элемента.DEVNULL
указывает, что будет использоваться специальный файлos.devnull
. При настройках по умолчаниюNone
перенаправление не происходит; дескрипторы дочерних файлов будут унаследованы от родительского. Кроме того, stderr может бытьSTDOUT
, что указывает на то, что данные stderr из дочернего процесса должны захватываться в тот же файловый дескриптор, что и для stdout.Если указаны encoding или errors, или text (также известный как universal_newlines) истинно, файловые объекты stdin, stdout и stderr будут открываться в текстовом режиме с использованием encoding и errors, указанных в вызове, или значений по умолчанию для
io.TextIOWrapper
.Для stdin символы окончания строки
'\n'
во входных данных будут преобразованы в разделитель строк по умолчаниюos.linesep
. Для stdout и stderr все окончания строк в выводе будут преобразованы в'\n'
. Дополнительные сведения см. в документации классаio.TextIOWrapper
, когда аргумент newline его конструктора —None
.Если текстовый режим не используется, stdin, stdout и stderr будут открыты как двоичные потоки. Кодирование или преобразование конца строки не выполняется.
Добавлено в версии 3.6: Добавлены параметры encoding и errors.
Добавлено в версии 3.7: Добавлен параметр text в качестве псевдонима для universal_newlines.
Примечание
Атрибут новой строки файловых объектов
Popen.stdin
,Popen.stdout
иPopen.stderr
не обновляется методомPopen.communicate()
.Если shell —
True
, указанная команда будет выполнена через оболочку. Полезно, если вы используете Python в первую очередь для расширенного потока управления, который он предлагает для большинства системных оболочек, и по-прежнему хотите удобный доступ к другим функциям оболочки, таким как конвейеры оболочки, подстановочные знаки имён файлов, расширение переменных среды и расширение~
до домашнего каталога пользователя. Однако обратите внимание, что сам Python предлагает реализации многих функций, подобных оболочке (в частности,glob
,fnmatch
,os.walk()
,os.path.expandvars()
,os.path.expanduser()
иshutil
).Изменено в версии 3.3: Когда universal_newlines —
True
, класс использует кодировкуlocale.getpreferredencoding(False)
вместоlocale.getpreferredencoding()
. См. классio.TextIOWrapper
для получения дополнительной информации об этом изменении.Примечание
Прочтите раздел Соображения безопасности перед использованием
shell=True
.
Параметры, наряду со всеми другими параметрами, более подробно описаны в
документации конструктора Popen
.
Конструктор Popen¶
Создание базового процесса и управление им в модуле осуществляется классом
Popen
. Он предлагает большую гибкость, так что разработчики могут
обрабатывать менее распространенные случаи, не охватываемые вспомогательными
функциями.
-
class
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=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None)¶ Выполнить дочернюю программу в новом процессе. В POSIX класс использует поведение, подобное
os.execvp()
, для выполнения дочерней программы. В Windows класс использует функцию WindowsCreateProcess()
. Аргументы в пользуPopen
заключаются в следующем.args должен быть последовательностью аргументов программы или отдельной строкой или путеподобным объектом. По умолчанию программа для выполнения является первым элементом в args, если args является последовательностью. Если args является строкой, интерпретация зависит от платформы и описана ниже. Дополнительные отличия от поведения по умолчанию см. в аргументах shell и executable. Если не указано иное, рекомендуется передавать args как последовательность.
Пример передачи некоторых аргументов внешней программе в виде последовательности:
Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."])
В POSIX, если args является строкой, строка интерпретируется как имя или путь выполняемой программы. Однако это можно сделать, только если не передать аргументы программе.
Примечание
Иногда неочевидно, как разбить команду оболочки на последовательность аргументов, особенно в сложных случаях.
shlex.split()
может проиллюстрировать, как определить правильную токенизацию для args:>>> import shlex, subprocess >>> command_line = input() /bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'" >>> args = shlex.split(command_line) >>> print(args) ['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"] >>> p = subprocess.Popen(args) # Успешно!
Обратите внимание, в частности, что параметры (например, -input) и аргументы (например, eggs.txt), разделенные пробелом в оболочке, помещаются в отдельные элементы списка, в то время как аргументы, которые требуют экранирования кавычек или обратной косой черты при использовании в оболочке (например, имена файлов, содержащие пробелы) или команда echo, показанная выше) являются отдельными элементами списка.
В Windows, если args является последовательностью, она будет преобразована в строку способом, описанным в Преобразование последовательности аргументов в строку в Windows. Это связано с тем, что базовый
CreateProcess()
работает со строками.Изменено в версии 3.6: Параметр args принимает путеподобный объект, если shell —
False
, и последовательность, содержащую путеподобные объекты в POSIX.Изменено в версии 3.8: Параметр args принимает путеподобный объект, если shell равен
False
, и последовательность, содержащую байты и путеподобные объекты в Windows.Аргумент shell (по умолчанию —
False
) указывает, следует ли использовать оболочку в качестве программы для выполнения. Если shell —True
, рекомендуется передавать args как строку, а не как последовательность.В POSIX с
shell=True
оболочка по умолчанию/bin/sh
. Если args является строкой, строка определяет команду, выполняемую через оболочку. Означает, что у строки должно быть точно так же форматирование, как при вводе в приглашении оболочки. Включает, например, кавычки или обратную косую черту, экранирующие имена файлов с пробелами. Если args представляет собой последовательность, первый элемент определяет командную строку, а любые дополнительные элементы будут рассматриваться как дополнительные аргументы для самой оболочки. То естьPopen
делает эквивалент:Popen(['/bin/sh', '-c', args[0], args[1], ...])
В Windows с
shell=True
переменная средыCOMSPEC
указывает оболочку по умолчанию. Единственный раз, когда вам нужно указатьshell=True
в Windows — когда команда, которую вы хотите выполнить, встроена в оболочку (например, dir или copy). Вам не нуженshell=True
для запуска командного файла или консольного исполняемого файла.Примечание
Прочтите раздел Соображения безопасности перед использованием
shell=True
.bufsize будет предоставлен в качестве соответствующего аргумента функции
open()
при создании файловых объектов конвейера (pipe) stdin/stdout/stderr:0
означает небуферизованный (чтение и запись являются одним системным вызовом и могут возвращать короткий)1
означает строковую буферизацию (используется, только еслиuniversal_newlines=True
, т. е. в текстовом режиме)- любое другое положительное значение означает использование буфера примерно такого размера
- отрицательный размер буфера (по умолчанию) означает, что будет использоваться системное значение по умолчанию io.DEFAULT_BUFFER_SIZE.
Изменено в версии 3.3.1: bufsize теперь по умолчанию содержит значение -1, чтобы включить буферизацию по умолчанию в соответствии с поведением, ожидаемым большинством кода. В версиях, предшествующих Python 3.2.4 и 3.3.1, по умолчанию было неправильно установлено значение
0
, которое не было буферизовано и допускало короткие чтения. Это было непреднамеренно и не соответствовало поведению Python 2, как ожидалось большинством кода.Аргумент executable указывает программу замены, которую нужно выполнить. Очень редко нужно. Когда
shell=False
, executable заменяет программу для выполнения, указанную в args. Однако исходный args по- прежнему передается в программу. Большинство программ рассматривают программу, указанную в args, как имя команды, которое может отличаться от фактически выполняемой программы. В POSIX имя args становится отображаемым именем исполняемого файла в таких утилитах, как ps. Еслиshell=True
, в POSIX аргумент executable указывает заменяющую оболочку для/bin/sh
по умолчанию.Изменено в версии 3.6: Параметр executable принимает путеподобный объект в POSIX.
Изменено в версии 3.8: Параметр executable принимает байты, а путеподобный объект в Windows.
stdin, stdout и stderr определяют обработчики стандартного ввода, стандартного вывода и стандартного файла ошибок исполняемой программы соответственно. Допустимые значения:
PIPE
,DEVNULL
, существующий дескриптор файла (положительное целое число), существующий файловый объект иNone
.PIPE
указывает, что необходимо создать новый конвейер для дочернего элемента.DEVNULL
указывает, что будет использоваться специальный файлos.devnull
. При настройках по умолчаниюNone
перенаправление не происходит; дескрипторы дочерних файлов будут унаследованы от родительского. Кроме того, stderr может бытьSTDOUT
, что указывает на то, что данные stderr из приложений должны быть захвачены в тот же дескриптор файла, что и для stdout.Если preexec_fn установлен как вызываемый объект, данный объект будет вызываться в дочернем процессе непосредственно перед выполнением дочернего процесса. (Только POSIX)
Предупреждение
Параметр preexec_fn небезопасно использовать при наличии потоков в вашем приложении. Дочерний процесс может зайти в тупик до вызова exec. Если вы должны его использовать, оставьте его тривиальным! Сведите к минимуму количество вызываемых вами библиотек.
Примечание
Если вам нужно изменить среду для ребенка, используйте параметр env вместо того, чтобы делать в preexec_fn. Параметр start_new_session может заменить ранее обычное использование preexec_fn для вызова os.setsid() в дочернем.
Изменено в версии 3.8: Параметр preexec_fn больше не поддерживается в субинтерпретаторах. Использование параметра в субинтерпретаторе вызывает
RuntimeError
. Новое ограничение может повлиять на приложения, развернутые в mod_wsgi, uWSGI и других встроенных средах.Если close_fds истинно, все дескрипторы файлов, кроме
0
,1
и2
, будут закрыты перед выполнением дочернего процесса. В противном случае, когда close_fds ложно, дескрипторы файлов подчиняются своему наследуемому флагу, как описано в Наследование файловых дескрипторов.В Windows, если close_fds истинно, то дескрипторы не будут унаследованы дочерним процессом, если явно не переданы в элементе
handle_list
STARTUPINFO.lpAttributeList
или с помощью стандартного перенаправления дескрипторов.Изменено в версии 3.2: Значение по умолчанию для close_fds было изменено с
False
на то, что описано выше.Изменено в версии 3.7: В Windows значение по умолчанию для close_fds было изменено с
False
наTrue
при перенаправлении стандартных дескрипторов. Теперь можно установить close_fds наTrue
при перенаправлении стандартных дескрипторов.pass_fds — необязательная последовательность файловых дескрипторов, которые должны оставаться открытыми между родительским и дочерним. Если указать любой pass_fds, то close_fds будет
True
. (Только POSIX)Изменено в версии 3.2: Добавлен параметр pass_fds.
Если cwd не
None
, функция изменяет рабочий каталог на cwd перед выполнением дочернего элемента. cwd может быть строкой, байтами или путеподобным объектом. В частности, функция ищет executable (или первый элемент в args) относительно cwd, если путь к исполняемому файлу является относительным.Изменено в версии 3.6: Параметр cwd принимает путеподобный объект в POSIX.
Изменено в версии 3.7: Параметр cwd принимает путеподобный объект в Windows.
Изменено в версии 3.8: Параметр cwd принимает байтовый объект в Windows.
Если restore_signals истинно (по умолчанию), все сигналы, которые Python установил в SIG_IGN, восстанавливаются в SIG_DFL в дочернем процессе перед exec. В настоящее время включает сигналы SIGPIPE, SIGXFZ и SIGXFSZ. (Только POSIX)
Изменено в версии 3.2: Был добавлен restore_signals.
Если start_new_session истинно, системный вызов setsid() будет выполнен в дочернем процессе до выполнения подпроцесса. (Только POSIX)
Изменено в версии 3.2: start_new_session был добавлен.
Если env не
None
, то должно быть отображение, которое определяет переменные среды для нового процесса; они используются вместо поведения по умолчанию при наследовании среды текущего процесса.Примечание
Если указано, env должен предоставлять все переменные, необходимые для выполнения программы. В Windows для запуска параллельной сборки указанный env должен включать действительный
SystemRoot
.Если указаны encoding или errors, или text истинно, объекты файлов stdin, stdout и stderr открываются в текстовом режиме с указанной кодировкой и errors, как описано выше в Часто используемые аргументы. Аргумент universal_newlines эквивалентен text и предоставляется для обратной совместимости. По умолчанию файловые объекты открываются в двоичном режиме.
Добавлено в версии 3.6: Добавлены encoding и errors.
Добавлено в версии 3.7: text был добавлен как более читаемый псевдоним для universal_newlines.
Если задано, startupinfo будет объектом
STARTUPINFO
, который передаётся в базовую функциюCreateProcess
. creationflags, если задан, может быть одним или несколькими из следующих флагов:Объекты Popen поддерживаются как менеджеры контекста с помощью оператора
with
: при выходе стандартные файловые дескрипторы закрываются, и процесс ожидает.with Popen(["ifconfig"], stdout=PIPE) as proc: log.write(proc.stdout.read())
Popen и другие функции в данном модуле, которые его используют, вызывают событие аудита
subprocess.Popen
с аргументамиexecutable
,args
,cwd
иenv
. Значениеargs
может быть одной строкой или списком строк, в зависимости от платформы.Изменено в версии 3.2: Добавлена поддержка менеджера контекста.
Изменено в версии 3.6: Деструктор Popen теперь выдает предупреждение
ResourceWarning
, если дочерний процесс всё ещё запущен.Изменено в версии 3.8: Popen может использовать
os.posix_spawn()
в некоторых случаях для повышения производительности. В подсистеме Windows для Linux и пользовательской эмуляции QEMU конструктор Popen, использующийos.posix_spawn()
, больше не вызывает исключение при таких ошибках, как отсутствие программы, но дочерний процесс завершается с ошибкой с ненулевым значениемreturncode
.
Исключения¶
Исключения, возникшие в дочернем процессе до начала выполнения новой программы, будут повторно вызваны в родительском процессе.
Чаще всего возникает исключение OSError
. Это происходит, например, при
попытке выполнить несуществующий файл. Приложения нужно подготовить к
исключениям OSError
.
ValueError
будет вызван, если Popen
вызывается с недопустимыми
аргументами.
check_call()
и check_output()
вызовут CalledProcessError
,
если вызываемый процесс вернёт ненулевой код возврата.
Все функции и методы, которые принимают параметр timeout, такие как
call()
и Popen.communicate()
, будут вызывать TimeoutExpired
,
если время ожидания истечет до завершения процесса.
Все исключения, определенные в данном модуле, наследуются от
SubprocessError
.
Добавлено в версии 3.3: Добавлен базовый класс
SubprocessError
.
Соображения безопасности¶
В отличие от некоторых других функций popen, реализация никогда не будет
неявно вызывать системную оболочку. Это означает, что все символы, включая
метасимволы оболочки, можно безопасно передавать дочерним процессам. Если
оболочка вызывается явно через shell=True
, ответственность за то, чтобы все
пробелы и метасимволы были указаны правильно, во избежание уязвимостей
инъекции оболочки,
является обязанностью приложения.
При использовании shell=True
функция shlex.quote()
может
использоваться для правильного экранирования пробелов и метасимволов оболочки в
строках, которые будут использоваться для создания команд оболочки.
Popen объекты¶
У экземпляров класса Popen
есть следующие методы:
-
Popen.
poll
()¶ Проверить, не завершился ли дочерний процесс. Установить и вернуть атрибут
returncode
. В противном случае возвращаетNone
.
-
Popen.
wait
(timeout=None)¶ Подождать, пока дочерний процесс завершится. Установить и вернуть атрибут
returncode
.Если процесс не завершается через timeout секунд, вызвать исключение
TimeoutExpired
. Можно безопасно перехватить исключение и повторить ожидание.Примечание
Приведёт к взаимоблокировке при использовании
stdout=PIPE
илиstderr=PIPE
, и дочерний процесс генерирует достаточно выходных данных для конвейера, чтобы он блокировал ожидание, пока буфер конвейера ОС не примет больше данных. Чтобы избежать этого, используйтеPopen.communicate()
при использовании конвейеров.Примечание
Функция реализована с использованием цикла занятости (неблокирующий вызов и короткие засыпания). Используйте модуль
asyncio
для асинхронного ожидания: см.asyncio.create_subprocess_exec
.Изменено в версии 3.3: Был добавлен timeout.
-
Popen.
communicate
(input=None, timeout=None)¶ Взаимодействие с процессом: отправка данных на stdin. Считывать данные из stdout и stderr, пока не будет достигнут конец файла. Подождать, пока процесс завершится, и установить атрибут
returncode
. Необязательным аргументом input должны быть данные, которые нужно отправить дочернему процессу, илиNone
, если данные не должны отправляться дочернему процессу. Если потоки открыты в текстовом режиме, input должен быть строкой. В противном случае — байтами.communicate()
возвращает кортеж(stdout_data, stderr_data)
. Данные будут строками, если потоки были открыты в текстовом режиме; в противном случае байты.Обратите внимание: если вы хотите отправлять данные в stdin процесса, вам необходимо создать объект Popen с
stdin=PIPE
. Точно так же, чтобы получить что-либо, кромеNone
в результирующем кортеже, вам нужно также указатьstdout=PIPE
и/илиstderr=PIPE
.Если процесс не завершится через timeout секунд, будет возбуждено исключение
TimeoutExpired
. Перехват этого исключения и повторная попытка связи не приведет к потере вывода.Дочерний процесс не уничтожается, если истекает время ожидания, поэтому для правильной очистки приложение с хорошим поведением должно убить дочерний процесс и завершить обмен данными:
proc = subprocess.Popen(...) try: outs, errs = proc.communicate(timeout=15) except TimeoutExpired: proc.kill() outs, errs = proc.communicate()
Примечание
Считанные данные буферизуются в памяти, поэтому не использовать этот метод, если размер данных большой или неограниченный.
Изменено в версии 3.3: Был добавлен timeout.
-
Popen.
send_signal
(signal)¶ Посылает ребенку сигнал signal.
Примечание
В Windows SIGTERM — псевдоним для
terminate()
. CTRL_C_EVENT и CTRL_BREAK_EVENT могут быть отправлены процессам, запущенным с параметром creationflags, который включает CREATE_NEW_PROCESS_GROUP.
-
Popen.
terminate
()¶ Остановить ребёнка. В операционных системах POSIX метод отправляет SIGTERM дочернему элементу. В Windows для остановки дочернего вызывается функция Win32 API
TerminateProcess()
.
-
Popen.
kill
()¶ Убивает дочерний процесс. В операционных системах POSIX функция отправляет дочернему элементу SIGKILL. В Windows
kill()
— псевдоним дляterminate()
.
Также доступны следующие атрибуты:
-
Popen.
args
¶ Аргумент args, переданный в
Popen
— последовательность аргументов программы или отдельная строка.Добавлено в версии 3.3.
-
Popen.
stdin
¶ Если аргумент stdin был
PIPE
, атрибут является записываемым объектом потока, возвращеннымopen()
. Если были указаны аргументы encoding или errors или аргумент universal_newlines былTrue
, поток является текстовым потоком, в противном случае это поток байтов. Если аргумент stdin не былPIPE
, этот атрибут —None
.
-
Popen.
stdout
¶ Если аргумент stdout был
PIPE
, атрибут является читаемым объектом потока, возвращеннымopen()
. Чтение из потока обеспечивает вывод дочернего процесса. Если были указаны аргументы encoding или errors или аргумент universal_newlines былTrue
, поток является текстовым потоком, в противном случае — потоком байтов. Если аргумент stdout не былPIPE
, у этого атрибута значениеNone
.
-
Popen.
stderr
¶ Если аргумент stderr был
PIPE
, атрибут является читаемым объектом потока, возвращеннымopen()
. Чтение из потока обеспечивает вывод ошибок дочернего процесса. Если были указаны аргументы encoding или errors или аргумент universal_newlines былTrue
, поток является текстовым потоком, в противном случае — потоком байтов. Если аргумент stderr не былPIPE
, атрибут —None
.
Предупреждение
Используйте communicate()
, а не .stdin.write
, .stdout.read
или .stderr.read
, чтобы избежать взаимоблокировок из-за заполнения любого из
других буферов конвейера ОС и блокировки дочернего процесса.
-
Popen.
pid
¶ ID дочернего процесса.
Обратите внимание, что если вы установить для аргумента shell значение
True
, будет ID процесса порождённой оболочки.
-
Popen.
returncode
¶ Дочерний код возврата, установленный
poll()
иwait()
(и косвенноcommunicate()
). ЗначениеNone
указывает на то, что процесс ещё не завершён.Отрицательное значение
-N
указывает, что дочерний был прерван сигналомN
(только POSIX).
Помощники Windows Popen¶
Класс STARTUPINFO
и следующие константы доступны только в Windows.
-
class
subprocess.
STARTUPINFO
(*, dwFlags=0, hStdInput=None, hStdOutput=None, hStdError=None, wShowWindow=0, lpAttributeList=None)¶ Для создания
Popen
используется частичная поддержка структуры Windows STARTUPINFO. Следующие атрибуты можно установить, передав их только в виде ключевых аргументов.Изменено в версии 3.7: Добавлена поддержка только ключевых аргументов.
-
dwFlags
¶ Битовое поле, которое определяет, используются ли определенные атрибуты
STARTUPINFO
, когда процесс создает окно.si = subprocess.STARTUPINFO() si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
-
hStdInput
¶ Если
dwFlags
указываетSTARTF_USESTDHANDLES
, атрибут является стандартным дескриптором ввода для процесса. ЕслиSTARTF_USESTDHANDLES
не указан, по умолчанию для стандартного ввода используется буфер клавиатуры.
-
hStdOutput
¶ Если
dwFlags
указываетSTARTF_USESTDHANDLES
, атрибут является стандартным дескриптором вывода для процесса. В противном случае данный атрибут игнорируется, и по умолчанию для стандартного вывода используется буфер окна консоли.
-
hStdError
¶ Если
dwFlags
указываетSTARTF_USESTDHANDLES
, атрибут является стандартным дескриптором ошибки для процесса. В противном случае данный атрибут игнорируется, и по умолчанию для стандартной ошибки используется буфер окна консоли.
-
wShowWindow
¶ Если
dwFlags
указываетSTARTF_USESHOWWINDOW
, атрибут может быть любым из значений, которые могут быть указаны в параметреnCmdShow
для функции ShowWindow, за исключениемSW_SHOWDEFAULT
. В противном случае данный атрибут игнорируется.Для данного атрибута предоставляется
SW_HIDE
. Он используется, когдаPopen
вызывается сshell=True
.
-
lpAttributeList
¶ Словарь дополнительных атрибутов для создания процесса, как указано в
STARTUPINFOEX
, см. UpdateProcThreadAttribute.Поддерживаемые атрибуты:
- handle_list
Последовательность наследуемых дескрипторов. close_fds — истинно, если не пусто.
Дескрипторы временно необходимо сделать наследуемыми
os.set_handle_inheritable()
при передаче в конструкторPopen
, иначеOSError
вызовется с ошибкой WindowsERROR_INVALID_PARAMETER
(87).Предупреждение
В многопоточном процессе соблюдайте осторожность, чтобы избежать утечки дескрипторов, помеченных как наследуемые, при объединении данной функции с одновременными вызовами других функций создания процесса, которые наследуют все дескрипторы, такие как
os.system()
. Это также относится к стандартному перенаправлению дескрипторов, которое временно создаёт наследуемые дескрипторы.
Добавлено в версии 3.7.
-
Константы Windows¶
Модуль subprocess
предоставляет следующие константы.
-
subprocess.
STD_INPUT_HANDLE
¶ Стандартное устройство ввода. Изначально буфер ввода консоли,
CONIN$
.
-
subprocess.
STD_OUTPUT_HANDLE
¶ Стандартное устройство вывода. Изначально активный экранный буфер консоли,
CONOUT$
.
-
subprocess.
STD_ERROR_HANDLE
¶ Стандартное устройство ошибок. Изначально активный экранный буфер консоли,
CONOUT$
.
-
subprocess.
SW_HIDE
¶ Скрывает окно. Другое окно будет активировано.
-
subprocess.
STARTF_USESTDHANDLES
¶ Указывает, что атрибуты
STARTUPINFO.hStdInput
,STARTUPINFO.hStdOutput
иSTARTUPINFO.hStdError
содержат дополнительную информацию.
-
subprocess.
STARTF_USESHOWWINDOW
¶ Указывает, что атрибут
STARTUPINFO.wShowWindow
содержит дополнительную информацию.
-
subprocess.
CREATE_NEW_CONSOLE
¶ У нового процесса новая консоль вместо наследования родительской консоли (по умолчанию).
-
subprocess.
CREATE_NEW_PROCESS_GROUP
¶ Параметр
Popen
creationflags
, указывает, что будет создана новая группа процессов. Флаг необходим для использованияos.kill()
в подпроцессе.Флаг игнорируется, если указан
CREATE_NEW_CONSOLE
.
-
subprocess.
ABOVE_NORMAL_PRIORITY_CLASS
¶ Параметр
Popen
creationflags
, указывающий, что у нового процесса будет приоритет выше среднего.Добавлено в версии 3.7.
-
subprocess.
BELOW_NORMAL_PRIORITY_CLASS
¶ Параметр
Popen
creationflags
, указывающий, что у нового процесса будет приоритет ниже среднего.Добавлено в версии 3.7.
-
subprocess.
HIGH_PRIORITY_CLASS
¶ Параметр
Popen
creationflags
, указывающий, что у нового процесса будет высокий приоритет.Добавлено в версии 3.7.
-
subprocess.
IDLE_PRIORITY_CLASS
¶ Параметр
Popen
creationflags
, указывающий, что у нового процесса будет неактивный (самый низкий) приоритет.Добавлено в версии 3.7.
-
subprocess.
NORMAL_PRIORITY_CLASS
¶ Параметр
Popen
creationflags
, указывающий, что у нового процесса будет нормальный приоритет. (По умолчанию.)Добавлено в версии 3.7.
-
subprocess.
REALTIME_PRIORITY_CLASS
¶ Параметр
Popen
creationflags
, указывающий, что у нового процесса будет приоритет в реальном времени. Практически никогда не следует использовать REALTIME_PRIORITY_CLASS, потому что прерывает системные потоки, которые управляют вводом мыши, вводом с клавиатуры и фоновой очисткой диска. Данный класс может подходить для приложений, которые «общаются» напрямую с оборудованием или выполняют короткие задачи, у которых ограниченные перерывы.Добавлено в версии 3.7.
-
subprocess.
CREATE_NO_WINDOW
¶ Параметр
Popen
creationflags
, указывающий, что новый процесс не будет создавать окно.Добавлено в версии 3.7.
-
subprocess.
DETACHED_PROCESS
¶ Параметр
Popen
creationflags
, указывающий, что новый процесс не будет наследовать консоль своего родителя. Значение нельзя использовать с CREATE_NEW_CONSOLE.Добавлено в версии 3.7.
-
subprocess.
CREATE_DEFAULT_ERROR_MODE
¶ Параметр
Popen
creationflags
, указывающий, что новый процесс не наследует режим ошибки вызывающего процесса. Вместо этого новый процесс получает режим ошибки по умолчанию. Функция особенно полезна для многопоточных приложений оболочки, которые работают с отключенными серьезными ошибками.Добавлено в версии 3.7.
Старый высокоуровневый API¶
До Python 3.5 три функции составляли высокоуровневый API для подпроцессов.
Теперь вы можете использовать run()
во многих случаях, но множество
существующих кодов вызывают данные функции.
-
subprocess.
call
(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)¶ Выполнить команду, описанную args. Дождаться завершения команды, затем вернуть атрибут
returncode
.Код, которому требуется захват stdout или stderr, должен использовать вместо этого
run()
:run(...).returncode
Чтобы подавить stdout или stderr, укажите значение
DEVNULL
.Приведенные выше аргументы — лишь некоторые общие. Полная сигнатура функции такая же, как у конструктора
Popen
— функция передаёт все предоставленные аргументы, кроме timeout, напрямую через данный интерфейс.Примечание
Не используйте с функцией
stdout=PIPE
илиstderr=PIPE
. Дочерний процесс блокируется, если он генерирует достаточно выходных данных для конвейера, чтобы заполнить буфер конвейера ОС, поскольку конвейеры не читаются.Изменено в версии 3.3: Добавлен timeout.
-
subprocess.
check_call
(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)¶ Запускает команду с аргументами. Дождается завершения команды. Если код возврата был равен нулю, то возвращает его, в противном случае вызывает
CalledProcessError
. У объектаCalledProcessError
будет код возврата в атрибутеreturncode
.Код, которому требуется захват stdout или stderr, должен использовать вместо неё
run()
:run(..., check=True)
Чтобы подавить stdout или stderr, укажите значение
DEVNULL
.Приведенные выше аргументы являются лишь частью общих. Полная сигнатура функции такая же, как у конструктора
Popen
— функция передаёт все предоставленные аргументы, кроме timeout, напрямую через данный интерфейс.Примечание
Не использовать с данной функцией
stdout=PIPE
илиstderr=PIPE
. Дочерний процесс блокируется, если он генерирует достаточно выходных данных для конвейера, чтобы заполнить буфер конвейера ОС, поскольку конвейеры не читаются.Изменено в версии 3.3: Был добавлен timeout.
-
subprocess.
check_output
(args, *, stdin=None, stderr=None, shell=False, cwd=None, encoding=None, errors=None, universal_newlines=None, timeout=None, text=None, **other_popen_kwargs)¶ Запустить команду с аргументами и вернуть её вывод.
Если код возврата был ненулевым, возникает
CalledProcessError
. У объектаCalledProcessError
будет код возврата в атрибутеreturncode
и любые выходные данные в атрибутеoutput
.Эквивалентно:
run(..., check=True, stdout=PIPE).stdout
Приведенные выше аргументы являются лишь частью общих. Полная сигнатура функции во многом такая же, как и у
run()
— большинство аргументов передаются напрямую в этот интерфейс. Существует одно отличие API от поведенияrun()
: передачаinput=None
будет вести себя так же, какinput=b''
(илиinput=''
, в зависимости от других аргументов), вместо использования стандартного дескриптора входного файла родителя.По умолчанию функция возвращает данные в виде закодированных байтов. Фактическое кодирование выходных данных может зависеть от вызываемой команды, поэтому декодирование в текст часто нужно будет обрабатывать на уровне приложения.
Данное поведение можно изменить, установив text, encoding, errors или universal_newlines на
True
, как описано в Часто используемые аргументы иrun()
.Чтобы также зафиксировать стандартную ошибку в результате, используйте
stderr=subprocess.STDOUT
:>>> subprocess.check_output( ... "ls non_existent_file; exit 0", ... stderr=subprocess.STDOUT, ... shell=True) 'ls: non_existent_file: No such file or directory\n'
Добавлено в версии 3.1.
Изменено в версии 3.3: Был добавлен timeout.
Изменено в версии 3.4: Добавлена поддержка ключевого аргумента input.
Изменено в версии 3.6: Добавлены encoding и errors. Подробнее см.
run()
.Добавлено в версии 3.7: text был добавлен как более читаемый псевдоним для universal_newlines.
Замена старых функций модулем subprocess
¶
В этом разделе «a становится b» означает, что b можно использовать как замену a.
Примечание
Все функции «a» в этом разделе завершаются ошибкой (более или менее), если
исполняемая программа не найдена; замена «b» вместо этого
вызывает OSError
.
Кроме того, замены с использованием check_output()
завершатся ошибкой
с CalledProcessError
, если запрошенная операция выдаст ненулевой код
возврата. Выходные данные по-прежнему доступны как атрибут
output
вызванного исключения.
В следующих примерах предполагается, что соответствующие функции уже
импортированы из модуля subprocess
.
Замена подстановки команд оболочки /bin/sh¶
output=$(mycmd myarg)
становится:
output = check_output(["mycmd", "myarg"])
Замена конвейера оболочки¶
output=$(dmesg | grep hda)
становится:
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close() # Разрешите p1 получить SIGPIPE, если p2 завершит работу.
output = p2.communicate()[0]
Вызов p1.stdout.close()
после запуска p2 важен для того, чтобы p1 получил
SIGPIPE, если p2 завершится до p1.
В качестве альтернативы для надежного ввода можно напрямую использовать поддержку собственного конвейера оболочки:
output=$(dmesg | grep hda)
становится:
output=check_output("dmesg | grep hda", shell=True)
Замена os.system()
¶
sts = os.system("mycmd" + " myarg")
# становится
sts = call("mycmd" + " myarg", shell=True)
Заметки:
- Вызов программы через оболочку обычно не требуется.
Более реалистичный пример мог бы выглядеть так:
try:
retcode = call("mycmd" + " myarg", shell=True)
if retcode < 0:
print("Child was terminated by signal", -retcode, file=sys.stderr)
else:
print("Child returned", retcode, file=sys.stderr)
except OSError as e:
print("Execution failed:", e, file=sys.stderr)
Замена семейства os.spawn
¶
P_NOWAIT пример:
pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
==>
pid = Popen(["/bin/mycmd", "myarg"]).pid
P_WAIT пример:
retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==>
retcode = call(["/bin/mycmd", "myarg"])
Векторный пример:
os.spawnvp(os.P_NOWAIT, path, args)
==>
Popen([path] + args[1:])
Пример окружения:
os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
==>
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})
Замена os.popen()
, os.popen2()
, os.popen3()
¶
(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)
(child_stdin,
child_stdout,
child_stderr) = os.popen3(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin,
child_stdout,
child_stderr) = (p.stdin, p.stdout, p.stderr)
(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
Обработка кода возврата переводится следующим образом:
pipe = os.popen(cmd, 'w')
...
rc = pipe.close()
if rc is not None and rc >> 8:
print("There were some errors")
==>
process = Popen(cmd, stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
print("There were some errors")
Замена функций из модуля popen2
¶
Примечание
Если аргумент cmd для функций popen2 является строкой, команда выполняется через /bin/sh. Если список, команда выполняется напрямую.
(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
==>
p = Popen("somestring", shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)
(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
==>
p = Popen(["mycmd", "myarg"], bufsize=bufsize,
stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)
popen2.Popen3
и popen2.Popen4
в основном работают как
subprocess.Popen
, за исключением следующего:
Popen
вызывает исключение в случае сбоя выполнения.- Аргумент capturestderr заменяется аргументом stderr.
- Необходимо указать
stdin=PIPE
иstdout=PIPE
. - popen2 закрывает все файловые дескрипторы по умолчанию, но вы должны указать
close_fds=True
сPopen
, чтобы гарантировать такое поведение на всех платформах или в предыдущих версиях Python.
Устаревшие функции вызова оболочки¶
Модуль также предоставляет следующие функции, унаследованные от модуля 2.x
commands
. Операции неявно вызывают системную оболочку, и ни одна из
описанных выше гарантий безопасности и согласованности обработки исключений не
действует для данных функций.
-
subprocess.
getstatusoutput
(cmd)¶ Вернуть
(exitcode, output)
при выполнении cmd в оболочке.Выполнить строку cmd в оболочке с
Popen.check_output()
и вернуть двухкортежный(exitcode, output)
. Используется кодировка локали; см. примечания к Часто используемые аргументы для получения более подробной информации.Завершающий символ новой строки удаляется из вывода. Код выхода для команды можно интерпретировать как код возврата подпроцесса. Пример:
>>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') >>> subprocess.getstatusoutput('cat /bin/junk') (1, 'cat: /bin/junk: No such file or directory') >>> subprocess.getstatusoutput('/bin/junk') (127, 'sh: /bin/junk: not found') >>> subprocess.getstatusoutput('/bin/kill $$') (-15, '')
Доступность: POSIX & Windows.
Изменено в версии 3.3.4: Добавлена поддержка Windows.
Теперь функция возвращает (код выхода, вывод) вместо (статус, вывод), как это было в Python 3.3.3 и ранее. У кода выхода то же значение, что и
returncode
.
-
subprocess.
getoutput
(cmd)¶ Возвращает вывод (stdout и stderr) выполнения cmd в оболочке.
Подобна
getstatusoutput()
, за исключением того, что код выхода игнорируется, а возвращаемое значение представляет собой строку, содержащую вывод команды. Пример:>>> subprocess.getoutput('ls /bin/ls') '/bin/ls'
Доступность: POSIX & Windows.
Изменено в версии 3.3.4: Добавлена поддержка Windows
Заметки¶
Преобразование последовательности аргументов в строку в Windows¶
В Windows последовательность args преобразуется в строку, которая может проанализирована с использованием следующих правил (которые соответствуют правилам, используемым средой выполнения MS C):
- Аргументы разделяются пробелом, который является либо пробелом, либо табуляцией.
- Строка, заключенная в двойные кавычки, интерпретируется как единственный аргумент, независимо от того, какие пробелы содержатся внутри. Строка в кавычках может встроена в аргумент.
- Двойные кавычки, которым предшествует обратная косая черта, интерпретируются как буквальные двойные кавычки.
- Обратные косые черты интерпретируются буквально, если они непосредственно не предшествуют двойным кавычкам.
- Если обратная косая черта непосредственно предшествует двойным кавычкам, каждая пара обратных косых черт интерпретируется как литеральная обратная косая черта. Если количество обратных косых черт нечетное, последняя обратная косая черта экранирует следующую двойную кавычку, как описано в правиле 3.
См.также
shlex
- Модуль предоставляет функцию для разбора и экранирования командных строк.