subprocess — Управление подпроцессами
Исходный код: Lib/subprocess.py
Модуль 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 имеет значение true, stdout и stderr будут захвачены. При использовании внутренний объект
Popenавтоматически создаётся сstdout=PIPEиstderr=PIPE. Аргументы stdout и stderr не могут быть заданы одновременно с capture_output. Если вы хотите захватить и объединить оба потока в один, используйтеstdout=PIPEиstderr=STDOUTвместо capture_output.Аргумент timeout передаётся в
Popen.communicate(). Если таймаут истекает, дочерний процесс будет убит, и будет дождано его завершение. ИсключениеTimeoutExpiredбудет повторно поднято после завершения дочернего процесса.Аргумент input передаётся в
Popen.communicate()и, таким образом, в стандартный ввод дочернего процесса. Если используется, он должен быть последовательностью байтов или строкой, если заданы encoding или errors, или если text имеет значение true. При использовании внутренний объектPopenавтоматически создаётся сstdin=PIPE, и аргумент stdin также использовать нельзя.Если check имеет значение true, и процесс завершается с ненулевым кодом возврата, будет поднято исключение
CalledProcessError. Атрибуты этого исключения содержат аргументы, код возврата и stdout и stderr, если они были захвачены.Если заданы encoding или errors, или text имеет значение true, файлы для stdin, stdout и stderr открываются в текстовом режиме с указанным encoding и errors или по умолчанию
io.TextIOWrapper. Аргумент universal_newlines эквивалентен text и предоставляется для обратной совместимости. По умолчанию файлы открываются в двоичном режиме.Если env не
None, он должен быть отображением, определяющим переменные среды для нового процесса; они используются вместо поведения по умолчанию по наследованию среды текущего процесса. Он передаётся напрямую вPopen.Примеры:
>>> subprocess.run(["ls", "-l"]) # doesn't capture output 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 -
Захваченный stdout из дочернего процесса. Последовательность байтов или строка, если
run()вызывалась с кодировкой, ошибками или text=True.Noneесли stdout не был захвачен.Если вы запустили процесс с
stderr=subprocess.STDOUT, stdout и stderr будут объединены в этом атрибуте, иstderrбудетNone.
-
stderr -
Захваченный stderr из дочернего процесса. Последовательность байтов или строка, если
run()вызывалась с кодировкой, ошибками или text=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и указывает, что должен быть открыт канал к стандартному потоку. Наиболее полезно сPopen.communicate().
-
subprocess.STDOUT -
Специальное значение, которое может быть использовано в качестве аргумента stderr для
Popenи указывает, что стандартная ошибка должна попадать в тот же обработчик, что и стандартный вывод.
-
exception subprocess.SubprocessError -
Базовый класс для всех других исключений из этого модуля.
Добавлена в версии 3.3.
-
exception subprocess.TimeoutExpired -
Подкласс
SubprocessError, поднимается при истечении таймаута при ожидании завершения дочернего процесса.-
cmd -
Команда, которая использовалась для запуска дочернего процесса.
-
timeout -
Таймаут в секундах.
-
output -
Вывод дочернего процесса, если он был захвачен
run()илиcheck_output(). В противном случае,None.
-
stdout -
Псевдоним для output, для симметрии с
stderr.
-
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.
-
stdout -
Псевдоним для output, для симметрии с
stderr.
-
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) равно True, объекты файлов 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.
Примечание
Атрибут 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) # Success!
Обратите особое внимание на то, что опции (например, -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()при создании объектов файлов stdin/stdout/stderr:-
0— без буферизации (чтение и запись выполняются одной системной вызовом и могут возвращать короткий результат) -
1— с буферизацией по строкам (используется только еслиuniversal_newlines=True— т.е. в текстовом режиме) - любое другое положительное значение — использовать буфер примерно такого размера
- отрицательное значение bufsize (по умолчанию) означает использование системного значения 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 имеет значение True, все дескрипторы файлов, кроме
0,1и2, будут закрыты перед выполнением дочернего процесса. В противном случае, при close_fds = False, дескрипторы файлов подчиняются своему флагу наследования, как описано в Наследование дескрипторов файлов.В Windows, если close_fds имеет значение True, то никакие дескрипторы не будут унаследованы дочерним процессом, если они не переданы явно в элементе
handle_listSTARTUPINFO.lpAttributeListили через стандартное перенаправление дескрипторов.Изменено в версии 3.2: Значение по умолчанию для close_fds было изменено с
Falseна описанное выше. -
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 равно true (по умолчанию), все сигналы, которые Python установил в SIG_IGN, восстанавливаются до SIG_DFL в дочернем процессе перед exec. В настоящее время это включает сигналы SIGPIPE, SIGXFZ и SIGXFSZ. (Только POSIX)
Изменено в версии 3.2: Добавлен параметр restore_signals.
Если start_new_session равно true, в дочернем процессе перед выполнением подпроцесса вызывается системный вызов setsid(). (Только POSIX)
Изменено в версии 3.2: Добавлен параметр start_new_session.
Если env не
None, он должен быть отображением, определяющим переменные среды для нового процесса; они используются вместо поведения по умолчанию, которое наследует среду текущего процесса.Примечание
Если указан env, он должен содержать все переменные, необходимые для выполнения программы. В Windows, для запуска side-by-side assembly указанный env **обязательно** должен включать допустимый
SystemRoot.Если указаны encoding или errors, или text равно true, объекты файлов stdin, stdout и stderr открываются в текстовом режиме с указанным encoding и errors, как описано выше в Часто используемые аргументы. Аргумент universal_newlines эквивалентен text и предоставляется для обратной совместимости. По умолчанию объекты файлов открываются в двоичном режиме.
Новое в версии 3.6: Добавлены encoding и errors.
Новое в версии 3.7: Добавлен text как более удобочитаемый псевдоним для universal_newlines.
Если указан, startupinfo будет объектом
STARTUPINFO, который передаётся в функцию низкого уровняCreateProcess. creationflags, если указаны, могут быть одним или несколькими из следующих флагов:CREATE_NEW_CONSOLECREATE_NEW_PROCESS_GROUPABOVE_NORMAL_PRIORITY_CLASSBELOW_NORMAL_PRIORITY_CLASSHIGH_PRIORITY_CLASSIDLE_PRIORITY_CLASSNORMAL_PRIORITY_CLASSREALTIME_PRIORITY_CLASSCREATE_NO_WINDOWDETACHED_PROCESSCREATE_DEFAULT_ERROR_MODECREATE_BREAKAWAY_FROM_JOB
Объекты 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 Subsystem for Linux и QEMU User Emulation, конструктор 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 injection.
При использовании shell=True, функция shlex.quote() может использоваться для правильного экранирования пробелов и метасимволов оболочки в строках, которые будут использоваться для создания команд оболочки.
Объекты Popen
Экземпляры класса Popen имеют следующие методы:
-
Popen.poll() -
Проверить, завершил ли дочерний процесс свою работу. Устанавливает и возвращает атрибут
returncode. В противном случае, возвращаетNone.
-
Popen.wait(timeout=None) -
Подождать завершения дочернего процесса. Устанавливает и возвращает атрибут
returncode.Если процесс не завершится после timeout секунд, будет поднято исключение
TimeoutExpired. Безопасно перехватывать это исключение и повторно пытаться выполнить ожидание.Примечание
Это приведёт к тупиковой ситуации при использовании
stdout=PIPEилиstderr=PIPEи дочерний процесс генерирует достаточно вывода в канал, так что он заблокируется, ожидая, пока буфер канала операционной системы примет больше данных. ИспользуйтеPopen.communicate()при использовании каналов, чтобы избежать этого.Примечание
Функция реализована с использованием цикла busy-wait (неблокирующий вызов и короткие паузы). Используйте модуль
asyncioдля асинхронного ожидания: см.asyncio.create_subprocess_exec.Изменено в версии 3.3: Добавлен параметр timeout.
-
Popen.communicate(input=None, timeout=None) -
Взаимодействие с процессом: Отправка данных в стандартный ввод. Чтение данных из стандартного вывода и стандартной ошибки, пока не будет достигнут конец файла. Дожидаться завершения процесса и установить атрибут
returncode. Необязательный аргумент input должен содержать данные, которые нужно отправить дочернему процессу, илиNone, если данные не нужно отправлять. Если потоки были открыты в текстовом режиме, input должен быть строкой. В противном случае это байты.communicate()возвращает кортеж(stdout_data, stderr_data). Данные будут строками, если потоки были открыты в текстовом режиме; в противном случае это байты.Обратите внимание, что если вы хотите отправить данные в стандартный ввод процесса, вам необходимо создать объект 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 -
Идентификатор процесса (PID) дочернего процесса.
Обратите внимание, что если вы установили аргумент shell в
True, это PID запущенной оболочки.
-
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) -
Частичная поддержка структуры Windows STARTUPINFO используется для создания
Popen. Следующие атрибуты можно установить, передав их в качестве ключевых аргументов.Изменено в версии 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 должно быть true, если список не пуст.
Дескрипторы должны быть временно сделаны наследуемыми с помощью
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для создания новой группы процессов. Этот флаг необходим для использованияos.kill()для дочернего процесса.Этот флаг игнорируется, если указан флаг
CREATE_NEW_CONSOLE.
-
subprocess.ABOVE_NORMAL_PRIORITY_CLASS -
Параметр
Popenдля задания повышенного приоритета нового процесса.Добавлена в версии 3.7.
-
subprocess.BELOW_NORMAL_PRIORITY_CLASS -
Параметр
Popenдля задания пониженного приоритета нового процесса.Добавлена в версии 3.7.
-
subprocess.HIGH_PRIORITY_CLASS -
Параметр
Popenдля задания высокого приоритета нового процесса.Добавлена в версии 3.7.
-
subprocess.IDLE_PRIORITY_CLASS -
Параметр
Popenдля задания приоритета нового процесса в режиме ожидания (низкий).Добавлена в версии 3.7.
-
subprocess.NORMAL_PRIORITY_CLASS -
Параметр
Popenдля задания нормального приоритета нового процесса (по умолчанию).Добавлена в версии 3.7.
-
subprocess.REALTIME_PRIORITY_CLASS -
Параметр
Popenдля задания приоритета нового процесса в режиме реального времени. Рекомендуется не использовать REALTIME_PRIORITY_CLASS, поскольку это может прерывать системные потоки, отвечающие за обработку ввода с мыши, клавиатуры и запись на диск. Этот класс может подойти для приложений, взаимодействующих напрямую с аппаратным обеспечением или выполняющих краткосрочные задачи, требующие минимальных прерываний.Добавлена в версии 3.7.
-
subprocess.CREATE_NO_WINDOW -
Параметр
Popenдля задания отсутствия окна у нового процесса.Добавлена в версии 3.7.
-
subprocess.DETACHED_PROCESS -
Параметр
Popenдля задания отсутствия наследования консоли родительского процесса. Это значение не может быть использовано вместе с CREATE_NEW_CONSOLE.Добавлена в версии 3.7.
-
subprocess.CREATE_DEFAULT_ERROR_MODE -
Параметр
Popenдля задания отсутствия наследования режима ошибок от вызывающего процесса. Вместо этого новый процесс получает режим ошибок по умолчанию. Эта функция особенно полезна для многопоточных оболочек, которые работают с отключёнными жёсткими ошибками.Добавлена в версии 3.7.
-
subprocess.CREATE_BREAKAWAY_FROM_JOB -
Параметр
Popenдля задания отсутствия связи нового процесса с задачей.Добавлена в версии 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() # Allow p1 to receive a SIGPIPE if p2 exits. 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")
# becomes
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()и возвращает 2-кортеж(exitcode, output). Используется кодировка локальной среды; см. примечания по Часто используемые аргументы для получения более подробной информации.Конец строки удаляется из вывода. Код завершения команды можно интерпретировать как код возврата subprocess. Пример:
>>> 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.
Функция теперь возвращает (exitcode, output) вместо (status, output), как это было в Python 3.3.3 и ранее. exitcode имеет то же значение, что и
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 runtime):
- Аргументы разделяются пробелами, которые могут быть пробелами или табуляцией.
- Строка, окружённая двойными кавычками, интерпретируется как один аргумент, независимо от пробелов внутри. В аргументе может быть вложена строка в кавычках.
- Двойная кавычка, предшествуемая обратной косой чертой, интерпретируется как двойная кавычка в прямом смысле.
- Обратные косые черты интерпретируются буквально, за исключением случаев, когда они непосредственно предшествуют двойной кавычке.
- Если обратные косые черты непосредственно предшествуют двойной кавычке, каждая пара обратных косых черт интерпретируется как обратная косая черта в прямом смысле. Если количество обратных косых черт нечётное, последняя обратная косая черта экранирует следующую двойную кавычку, как описано в правиле 3.
См. также
-
shlex -
Модуль, предоставляющий функции для разбора и экранирования командных строк.
© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.8/library/subprocess.html