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()илиrun()(сcheck=True) возвращает код завершения, отличный от нуля.-
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) истинно, объекты файлов 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=(), *, group=None, extra_groups=None, user=None, umask=-1, 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.
Если group не
None, вызов системной функции setregid() будет выполнен в дочернем процессе перед выполнением подпроцесса. Если предоставленное значение является строкой, оно будет найдено с помощьюgrp.getgrnam(), и будет использовано значение вgr_gid. Если значение является целым числом, оно будет передано без изменений. (Только POSIX)Доступность: POSIX
Новое в версии 3.9.
Если extra_groups не
None, вызов системной функции setgroups() будет выполнен в дочернем процессе перед выполнением подпроцесса. Строковые значения в extra_groups будут найдены с помощьюgrp.getgrnam(), и значения вgr_gidбудут использованы. Целочисленные значения будут переданы без изменений. (Только POSIX)Доступность: POSIX
Новое в версии 3.9.
Если user не
None, вызов системной функции setreuid() будет выполнен в дочернем процессе перед выполнением подпроцесса. Если предоставленное значение является строкой, оно будет найдено с помощьюpwd.getpwnam(), и будет использовано значение вpw_uid. Если значение является целым числом, оно будет передано без изменений. (Только POSIX)Доступность: POSIX
Новое в версии 3.9.
Если umask не отрицательное значение, вызов системной функции umask() будет выполнен в дочернем процессе перед выполнением подпроцесса.
Доступность: POSIX
Новое в версии 3.9.
Если env не
None, это должно быть отображение, определяющее переменные среды для нового процесса; они используются вместо стандартного поведения наследования среды текущего процесса.Примечание
Если указано, env должен предоставить все переменные, необходимые для выполнения программы. В Windows, для запуска side-by-side assembly указанное env обязательно должно включать корректную
SystemRoot.Если указаны encoding или errors, или text имеет значение true, объекты файлов stdin, stdout и stderr открываются в текстовом режиме с указанным кодированием и 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. Обратите внимание, что, когда shell=True, 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()при использовании каналов, чтобы избежать этого.Примечание
Функция реализована с помощью цикла busy loop (неблокирующий вызов и короткие паузы). Используйте модуль
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 высокого уровня для subprocess. Теперь вы можете использовать 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. Еслиcheck_call()не смог запустить процесс, то будет распространено сгенерированное исключение.Код, которому нужно захватить 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()— большинство аргументов передаются напрямую этому интерфейсу. Отклонение от поведенияrun()в API состоит в том, что передача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
retcode = call("mycmd" + " myarg", shell=True)
Примечания:
- Вызов программы через оболочку обычно не требуется.
- Значение возврата
call()закодировано иначе, чем значение возвратаos.system(). - Функция
os.system()игнорирует сигналы SIGINT и SIGQUIT во время выполнения команды, но вызывающая сторона должна сделать это отдельно при использовании модуляsubprocess.
Более реалистичный пример выглядит так:
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. Пример:
>>> 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.9/library/subprocess.html