subprocess — Управление подпроцессами
Исходный код: Lib/subprocess.py
Модуль subprocess позволяет запускать новые процессы, подключаться к их каналам ввода/вывода/ошибок и получать их коды возврата. Этот модуль призван заменить несколько устаревших модулей и функций:
os.system os.spawn*
Сведения о том, как модуль subprocess можно использовать для замены этих модулей и функций, приведены в следующих разделах.
См. также
PEP 324 — предложение PEP о модуле subprocess
Доступность: недоступен на Android, iOS и WASI.
Этот модуль не поддерживается на мобильных платформах и платформах WebAssembly.
Использование модуля subprocess
Рекомендуемый подход к запуску подпроцессов во всех поддерживаемых случаях — использовать функцию run(). Для более сложных случаев можно напрямую использовать базовый интерфейс Popen.
-
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 и stderr, установленными вPIPE. Аргументы stdout и stderr нельзя указывать одновременно с capture_output. Если необходимо захватить оба потока и объединить их в один, вместо использования capture_output установите для stdout значениеPIPE, а для stderr —STDOUT.Параметр timeout можно задать в секундах; он передаётся методу
Popen.communicate(). Если время ожидания истекает, дочерний процесс будет завершён, после чего функция дождётся его завершения. ИсключениеTimeoutExpiredбудет повторно вызвано после завершения дочернего процесса. На многих платформенных API нельзя прервать само создание процесса, поэтому исключение о превышении времени ожидания гарантированно возникнет не раньше, чем завершится создание процесса.Аргумент input передаётся методу
Popen.communicate(), а следовательно, и стандартному потоку ввода stdin подпроцесса. Если он используется, его значением должна быть последовательность байтов или строка, если задан параметр 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. На любой платформе это отображение может содержать строки в качестве ключей и значений, а на платформах POSIX — байтовые строки, подобноos.environилиos.environb.Примеры:
>>> 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.
Изменено в версии 3.12: Изменён порядок поиска оболочки в Windows для
shell=True. Текущий каталог и%PATH%заменяются на%COMSPEC%и%SystemRoot%\System32\cmd.exe. В результате больше не удастся запустить вредоносную программу с именемcmd.exe, помещённую в текущий каталог.
-
class subprocess.CompletedProcess -
Возвращаемое значение функции
run(), представляющее завершившийся процесс.-
args -
Аргументы, использованные для запуска процесса. Это может быть список или строка.
-
returncode -
Код завершения дочернего процесса. Обычно код завершения 0 означает, что процесс выполнился успешно.
Отрицательное значение
-Nуказывает, что дочерний процесс был завершён сигналомN(только POSIX).
-
stdout -
Захваченный поток stdout дочернего процесса. Последовательность байтов или строка, если функция
run()была вызвана с параметром encoding, errors или text=True.None, если stdout не был захвачен.Если процесс был запущен с
stderr=subprocess.STDOUT, stdout и stderr будут объединены в этом атрибуте, аstderrбудет иметь значениеNone.
-
stderr -
Захваченный поток stderr дочернего процесса. Последовательность байтов или строка, если функция
run()была вызвана с параметром encoding, errors или 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. Если вывод был захвачен, его тип всегдаbytes, независимо от настройкиtext=True. Если вывод не наблюдался, значением может остатьсяNone, а неb''.
-
stdout -
Синоним output, используемый для симметрии с
stderr.
-
stderr -
Вывод stderr дочернего процесса, если он был захвачен функцией
run(). В противном случае —None. Если вывод stderr был захвачен, его тип всегдаbytes, независимо от настройкиtext=True. Если вывод stderr не наблюдался, значением может остатьсяNone, а неb''.
Добавлено в версии 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 задают файловые дескрипторы стандартного ввода, стандартного вывода и стандартного потока ошибок выполняемой программы соответственно. Допустимые значения: None, PIPE, DEVNULL, существующий файловый дескриптор (положительное целое число) и существующий файловый объект с допустимым файловым дескриптором. При настройках None по умолчанию перенаправление не выполняется. PIPE означает, что для дочернего процесса следует создать новый канал. DEVNULL указывает, что будет использоваться специальный файл os.devnull. Кроме того, аргумент 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=(), *, group=None, extra_groups=None, user=None, umask=-1, encoding=None, errors=None, text=None, pipesize=-1, process_group=None) -
Запускает дочернюю программу в новом процессе. В POSIX класс использует поведение, аналогичное
os.execvpe(), для запуска дочерней программы. В Windows класс использует функцию WindowsCreateProcess(). АргументыPopenописаны ниже.args должен быть последовательностью аргументов программы либо одной строкой или объектом, подобным пути. По умолчанию запускается программа, указанная первым элементом args, если args — последовательность. Если args — строка, её интерпретация зависит от платформы и описана ниже. Дополнительные отличия от поведения по умолчанию см. в описании аргументов shell и executable. Если не указано иное, рекомендуется передавать args как последовательность.
Предупреждение
Для максимальной надёжности указывайте для исполняемого файла полный путь. Чтобы найти файл по неполному имени в
PATH, используйтеshutil.which(). На всех платформах рекомендуется передаватьsys.executable, чтобы снова запустить текущий интерпретатор Python, а для запуска установленного модуля используйте формат командной строки-m.Разрешение пути к executable (или первому элементу args) зависит от платформы. В POSIX см.
os.execvpe(). Обратите внимание: при разрешении или поиске пути к исполняемому файлу cwd переопределяет текущий рабочий каталог, а env может переопределить переменную средыPATH. В Windows см. документацию по параметрамlpApplicationNameиlpCommandLineфункции WinAPICreateProcess. Обратите внимание: при разрешении или поиске пути к исполняемому файлу с помощьюshell=Falsecwd не переопределяет текущий рабочий каталог, а env не может переопределить переменную средыPATH. Использование полного пути позволяет избежать всех этих различий.Пример передачи внешней программе нескольких аргументов в виде последовательности:
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означает построчную буферизацию (можно использовать только приtext=Trueили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.
Изменено в версии 3.12: Изменён порядок поиска оболочки в Windows для
shell=True. Текущий каталог и%PATH%заменены на%COMSPEC%и%SystemRoot%\System32\cmd.exe. В результате больше не получится запустить вредоносную программу с именемcmd.exe, помещённую в текущий каталог.stdin, stdout и stderr задают файловые дескрипторы стандартного ввода, стандартного вывода и стандартного потока ошибок запускаемой программы соответственно. Допустимые значения:
None,PIPE,DEVNULL, существующий файловый дескриптор (положительное целое число) и существующий файловый объект с допустимым файловым дескриптором. При настройкахNoneпо умолчанию перенаправление не выполняется.PIPEозначает, что для дочернего процесса следует создать новый канал.DEVNULLозначает, что будет использоваться специальный файлos.devnull. Кроме того, для stderr можно указатьSTDOUT, что означает сбор данных stderr приложений в тот же файловый дескриптор, что и для stdout.Если preexec_fn задан вызываемым объектом, этот объект будет вызван в дочернем процессе непосредственно перед запуском дочерней программы. (Только POSIX)
Предупреждение
Параметр preexec_fn НЕБЕЗОПАСНО использовать в приложении с потоками. Дочерний процесс может взаимоблокироваться до вызова exec.
Примечание
Если необходимо изменить окружение дочернего процесса, используйте параметр env, а не делайте это в preexec_fn. Параметры start_new_session и process_group должны заменить код, использующий preexec_fn для вызова
os.setsid()илиos.setpgid()в дочернем процессе.Изменено в версии 3.8: Параметр preexec_fn больше не поддерживается во вложенных интерпретаторах. Использование этого параметра во вложенном интерпретаторе вызывает
RuntimeError. Это новое ограничение может затронуть приложения, развёрнутые в mod_wsgi, uWSGI и других встраиваемых средах.Если close_fds имеет значение true, перед запуском дочернего процесса будут закрыты все файловые дескрипторы, кроме
0,1и2. Если же close_fds имеет значение false, файловые дескрипторы наследуются в соответствии с флагом inheritable, как описано в разделе Наследование файловых дескрипторов.В Windows, если close_fds имеет значение true, дочерний процесс не наследует никакие дескрипторы, за исключением явно переданных в элементе
handle_listатрибутаSTARTUPINFO.lpAttributeListили перенаправленных стандартных дескрипторов.Изменено в версии 3.2: Значение close_fds по умолчанию изменено с
Falseна описанное выше.Изменено в версии 3.7: В Windows значение close_fds по умолчанию при перенаправлении стандартных дескрипторов изменено с
FalseнаTrue. Теперь при перенаправлении стандартных дескрипторов можно задать для close_fds значениеTrue.pass_fds — необязательная последовательность файловых дескрипторов, которые следует оставить открытыми между родительским и дочерним процессами. Передача любого значения pass_fds принудительно устанавливает для close_fds значение
True. (Только POSIX)Изменено в версии 3.2: Добавлен параметр pass_fds.
Если cwd не равен
None, функция меняет рабочий каталог на cwd перед запуском дочернего процесса. cwd может быть строкой, байтами или объектом, подобным пути. В POSIX функция ищет executable (или первый элемент args) относительно cwd, если путь к исполняемому файлу относительный.Изменено в версии 3.6: Параметр cwd принимает объект, подобный пути, в POSIX.
Изменено в версии 3.7: Параметр cwd принимает объект, подобный пути, в Windows.
Изменено в версии 3.8: Параметр cwd принимает объект bytes в 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.
Если process_group — неотрицательное целое число, системный вызов
setpgid(0, value)будет выполнен в дочернем процессе перед запуском подпроцесса.Доступность: POSIX
Изменено в версии 3.11: Добавлен параметр process_group.
Если 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)Примечание
Указание user не удаляет существующее членство во вспомогательных группах! Чтобы в целях безопасности сократить членство дочернего процесса в группах, вызывающий код должен также передать
extra_groups=().Доступность: POSIX
Добавлено в версии 3.9.
Если umask неотрицателен, системный вызов umask() будет выполнен в дочернем процессе перед запуском подпроцесса.
Доступность: POSIX
Добавлено в версии 3.9.
Если env не равен
None, он должен быть отображением, задающим переменные среды для нового процесса; они используются вместо поведения по умолчанию, при котором наследуется окружение текущего процесса. Это отображение может содержать пары str — str на любой платформе или bytes — bytes на платформах POSIX, подобноos.environилиos.environb.Примечание
Если задан параметр env, он должен содержать все переменные, необходимые для запуска программы. В Windows для запуска параллельной сборки заданный 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
Параметр pipesize позволяет изменить размер канала, если для stdin, stdout или stderr используется
PIPE. Размер канала изменяется только на платформах, которые это поддерживают (на данный момент только Linux). На других платформах этот параметр игнорируется.Изменено в версии 3.10: Добавлен параметр pipesize.
Объекты Popen поддерживают использование в качестве менеджеров контекста с оператором
with: при выходе стандартные файловые дескрипторы закрываются, а выполнение процесса ожидается.with Popen(["ifconfig"], stdout=PIPE) as proc: log.write(proc.stdout.read())Popen и другие функции этого модуля, использующие его, вызывают событие аудита
subprocess.Popenс аргументамиexecutable,args,cwdиenv. Значениеargsможет быть одной строкой или списком строк в зависимости от платформы.Изменено в версии 3.2: Добавлена поддержка менеджера контекста.
Изменено в версии 3.6: Теперь деструктор Popen выдаёт предупреждение
ResourceWarning, если дочерний процесс всё ещё выполняется.Изменено в версии 3.8: В некоторых случаях Popen может использовать
os.posix_spawn()для повышения производительности. В подсистеме Windows для Linux и эмуляции пользовательского режима QEMU конструктор Popen сos.posix_spawn()больше не вызывает исключение при ошибках, например если программа не найдена; вместо этого дочерний процесс завершается с ненулевым значениемreturncode. -
Исключения
Исключения, возникшие в дочернем процессе до начала выполнения новой программы, повторно вызываются в родительском процессе.
Наиболее часто возникает исключение OSError. Например, это происходит при попытке запустить несуществующий файл. Приложения должны быть готовы к исключениям OSError. Обратите внимание: при shell=True исключение OSError будет вызвано дочерним процессом, только если выбранная оболочка не найдена. Чтобы определить, не удалось ли оболочке найти запрошенное приложение, необходимо проверить код возврата или вывод подпроцесса.
Исключение ValueError будет вызвано, если Popen вызван с недопустимыми аргументами.
check_call() и check_output() вызовут CalledProcessError, если вызванный процесс завершится с ненулевым кодом возврата.
Все функции и методы, принимающие параметр timeout, например run() и Popen.communicate(), вызовут TimeoutExpired, если время ожидания истечёт до завершения процесса.
Все исключения, определённые в этом модуле, наследуются от SubprocessError.
Добавлено в версии 3.3: Добавлен базовый класс SubprocessError.
Вопросы безопасности
В отличие от некоторых других функций popen, эта библиотека не выбирает неявно системную оболочку. Это означает, что все символы, включая специальные символы оболочки, можно безопасно передавать дочерним процессам. Если оболочка вызывается явно с помощью shell=True, приложение должно обеспечить правильное экранирование всех пробелов и специальных символов, чтобы избежать уязвимостей, связанных с инъекцией команд оболочки. На некоторых платформах для такого экранирования можно использовать shlex.quote().
В Windows командные файлы (*.bat или *.cmd) могут запускаться операционной системой в системной оболочке независимо от аргументов, переданных этой библиотеке. В результате аргументы могут обрабатываться по правилам оболочки, но Python не добавит необходимое экранирование. Если вы намеренно запускаете командный файл с аргументами из ненадёжных источников, рассмотрите возможность передачи shell=True, чтобы Python экранировал специальные символы. Дополнительное обсуждение см. в gh-114539.
Объекты Popen
Экземпляры класса Popen имеют следующие методы:
-
Popen.poll() -
Проверяет, завершился ли дочерний процесс. Устанавливает и возвращает атрибут
returncode. В противном случае возвращаетNone.
-
Popen.wait(timeout=None) -
Ожидает завершения дочернего процесса. Устанавливает и возвращает атрибут
returncode.Если процесс не завершится за timeout секунд, возникает исключение
TimeoutExpired. Это исключение можно безопасно перехватить и повторить ожидание.Примечание
При использовании
stdout=PIPEилиstderr=PIPEэто приведёт к взаимной блокировке, если дочерний процесс выдаст в канал достаточно данных, чтобы заблокироваться в ожидании освобождения места в буфере канала ОС. Чтобы избежать этого при использовании каналов, применяйтеPopen.communicate().Примечание
Если параметр
timeoutне равенNone, функция (в POSIX) реализована с помощью активного ожидания (неблокирующий вызов и короткие паузы). Для асинхронного ожидания используйте модульasyncio: см.asyncio.create_subprocess_exec.Изменено в версии 3.3: добавлен параметр timeout.
-
Popen.communicate(input=None, timeout=None) -
Взаимодействует с процессом: отправляет данные в stdin. Считывает данные из stdout и stderr до достижения конца файла. Ожидает завершения процесса и устанавливает атрибут
returncode. Необязательный аргумент input должен содержать данные для отправки дочернему процессу илиNone, если дочернему процессу не нужно отправлять данные. Если потоки открыты в текстовом режиме, input должен быть строкой. В противном случае это должны быть байты.communicate()возвращает кортеж(stdout_data, stderr_data). Если потоки открыты в текстовом режиме, данные будут представлены строками; в противном случае — байтами.Обратите внимание: чтобы отправлять данные в stdin процесса, необходимо создать объект Popen с параметром
stdin=PIPE. Аналогично, чтобы получить в кортеже результата что-либо, кромеNone, необходимо также указатьstdout=PIPEи/илиstderr=PIPE.Если процесс не завершится за timeout секунд, будет возбуждено исключение
TimeoutExpired. Перехват этого исключения и повторная попытка взаимодействия не приведут к потере выходных данных. Передача input при последующем вызовеcommunicate()после истечения времени ожидания имеет неопределённое поведение и в будущем может привести к ошибке.Дочерний процесс не завершается принудительно по истечении времени ожидания, поэтому для надлежащей очистки правильно работающему приложению следует завершить дочерний процесс и закончить обмен данными:
proc = subprocess.Popen(...) try: outs, errs = proc.communicate(timeout=15) except TimeoutExpired: proc.kill() outs, errs = proc.communicate()Если вызов
communicate()возбуждает исключениеTimeoutExpired, не вызывайтеwait(). Выполните дополнительный вызовcommunicate(), чтобы завершить обработку каналов и заполнить атрибутreturncode.Примечание
Считанные данные буферизуются в памяти, поэтому не используйте этот метод, если объём данных велик или не ограничен.
Изменено в версии 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 для остановки дочернего процесса вызывается функция API Win32TerminateProcess().
-
Popen.kill() -
Завершает дочерний процесс. В POSIX функция отправляет дочернему процессу сигнал SIGKILL. В Windows
kill()является псевдонимом дляterminate().
Класс также устанавливает следующие атрибуты, доступные для использования. Переназначать им новые значения не поддерживается:
-
Popen.args -
Аргумент args в том виде, в каком он был передан в
Popen: последовательность аргументов программы или одна строка.Добавлено в версии 3.3.
-
Popen.stdin -
Если аргумент stdin равен
PIPE, этот атрибут является доступным для записи потоковым объектом, возвращаемымopen(). Если указаны аргументы encoding или errors либо аргумент text или universal_newlines равенTrue, поток является текстовым; в противном случае это байтовый поток. Если аргумент stdin не равенPIPE, этот атрибут равенNone.
-
Popen.stdout -
Если аргумент stdout равен
PIPE, этот атрибут является доступным для чтения потоковым объектом, возвращаемымopen(). Чтение из потока предоставляет выходные данные дочернего процесса. Если указаны аргументы encoding или errors либо аргумент text или universal_newlines равенTrue, поток является текстовым; в противном случае это байтовый поток. Если аргумент stdout не равенPIPE, этот атрибут равенNone.
-
Popen.stderr -
Если аргумент stderr равен
PIPE, этот атрибут является доступным для чтения потоковым объектом, возвращаемымopen(). Чтение из потока предоставляет сообщения об ошибках дочернего процесса. Если указаны аргументы encoding или errors либо аргумент text или universal_newlines равенTrue, поток является текстовым; в противном случае это байтовый поток. Если аргумент stderr не равенPIPE, этот атрибут равенNone.
Предупреждение
Используйте communicate(), а не .stdin.write, .stdout.read или .stderr.read, чтобы избежать взаимной блокировки из-за заполнения буферов других каналов ОС и блокировки дочернего процесса.
-
Popen.pid -
Идентификатор процесса дочернего процесса.
Обратите внимание: если аргумент shell установлен в
True, это идентификатор запущенной оболочки.
-
Popen.returncode -
Код возврата дочернего процесса. Изначально равен
None; значениеreturncodeустанавливается методамиpoll(),wait()илиcommunicate(), если они обнаруживают, что процесс завершился.Значение
Noneуказывает, что на момент последнего вызова метода процесс ещё не завершился.Отрицательное значение
-Nуказывает, что дочерний процесс был завершён сигналомN(только POSIX).Если задано
shell=True, код возврата отражает состояние завершения самой оболочки (например,/bin/sh), которое может преобразовывать сигналы в такие коды, как128+N. Подробности см. в документации оболочки (например, в разделе Exit Status руководства Bash).
Вспомогательные средства Popen для Windows
Класс STARTUPINFO и следующие константы доступны только в Windows.
-
class subprocess.STARTUPINFO(*, dwFlags=0, hStdInput=None, hStdOutput=None, hStdError=None, wShowWindow=0, lpAttributeList=None) -
Для создания
Popenиспользуется частичная поддержка структуры Windows STARTUPINFO. Следующие атрибуты можно задать, передав их как аргументы только по имени.Изменено в версии 3.7: добавлена поддержка аргументов только по имени.
-
dwFlags -
Битовое поле, определяющее, используются ли определённые атрибуты
STARTUPINFOпри создании окном процесса.si = subprocess.STARTUPINFO() si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
-
hStdInput -
Если
dwFlagsуказываетSTARTF_USESTDHANDLES, этот атрибут является дескриптором стандартного ввода процесса. ЕслиSTARTF_USESTDHANDLESне указано, стандартным вводом по умолчанию является буфер клавиатуры.
-
hStdOutput -
Если
dwFlagsуказываетSTARTF_USESTDHANDLES, этот атрибут является дескриптором стандартного вывода процесса. В противном случае этот атрибут игнорируется, а стандартным выводом по умолчанию является буфер окна консоли.
-
hStdError -
Если
dwFlagsуказываетSTARTF_USESTDHANDLES, этот атрибут является дескриптором стандартного вывода ошибок процесса. В противном случае этот атрибут игнорируется, а стандартным выводом ошибок по умолчанию является буфер окна консоли.
-
wShowWindow -
Если
dwFlagsуказываетSTARTF_USESHOWWINDOW, этот атрибут может принимать любое значение, допустимое для параметраnCmdShowфункции ShowWindow, кромеSW_SHOWDEFAULT. В противном случае этот атрибут игнорируется.Для этого атрибута предусмотрено значение
SW_HIDE. Оно используется, когдаPopenвызывается сshell=True.
-
lpAttributeList -
Словарь дополнительных атрибутов создания процесса, передаваемый в
STARTUPINFOEX; см. UpdateProcThreadAttribute.Поддерживаемые атрибуты:
- handle_list
-
Последовательность дескрипторов, которые будут унаследованы. Если последовательность не пуста, close_fds должен иметь значение true.
При передаче конструктору
Popenдескрипторы необходимо временно сделать наследуемыми с помощьюos.set_handle_inheritable(); в противном случае будет возбуждено исключение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.STARTF_FORCEONFEEDBACK -
Параметр
STARTUPINFO.dwFlags, указывающий, что при запуске процесса будет отображаться курсор мыши «Работа в фоновом режиме». Это поведение по умолчанию для процессов с графическим интерфейсом.Добавлено в версии 3.13.
-
subprocess.STARTF_FORCEOFFFEEDBACK -
Параметр
STARTUPINFO.dwFlags, указывающий, что при запуске процесса курсор мыши не будет изменён.Добавлено в версии 3.13.
-
subprocess.CREATE_NEW_CONSOLE -
Новый процесс получает новую консоль, а не наследует консоль родительского процесса (поведение по умолчанию).
-
subprocess.CREATE_NEW_PROCESS_GROUP -
Параметр
creationflagsдляPopen, указывающий, что будет создана новая группа процессов. Этот флаг необходим для использованияos.kill()для подпроцесса.Этот флаг игнорируется, если указан
CREATE_NEW_CONSOLE.
-
subprocess.ABOVE_NORMAL_PRIORITY_CLASS -
Параметр
creationflagsдляPopen, указывающий, что новый процесс будет иметь приоритет выше среднего.Добавлено в версии 3.7.
-
subprocess.BELOW_NORMAL_PRIORITY_CLASS -
Параметр
creationflagsдляPopen, указывающий, что новый процесс будет иметь приоритет ниже среднего.Добавлено в версии 3.7.
-
subprocess.HIGH_PRIORITY_CLASS -
Параметр
creationflagsдляPopen, указывающий, что новый процесс будет иметь высокий приоритет.Добавлено в версии 3.7.
-
subprocess.IDLE_PRIORITY_CLASS -
Параметр
creationflagsдляPopen, указывающий, что новый процесс будет иметь низший приоритет (наименьший).Добавлено в версии 3.7.
-
subprocess.NORMAL_PRIORITY_CLASS -
Параметр
creationflagsдляPopen, указывающий, что новый процесс будет иметь обычный приоритет (по умолчанию).Добавлено в версии 3.7.
-
subprocess.REALTIME_PRIORITY_CLASS -
Параметр
creationflagsдляPopen, указывающий, что новый процесс будет иметь приоритет реального времени. Почти никогда не следует использовать REALTIME_PRIORITY_CLASS, поскольку это прерывает системные потоки, обрабатывающие ввод с мыши и клавиатуры, а также фоновую запись данных на диск. Этот класс может подходить приложениям, которые взаимодействуют напрямую с оборудованием или выполняют кратковременные задачи, требующие минимального числа прерываний.Добавлено в версии 3.7.
-
subprocess.CREATE_NO_WINDOW -
Параметр
creationflagsдляPopen, указывающий, что новый процесс не будет создавать окно.Добавлено в версии 3.7.
-
subprocess.DETACHED_PROCESS -
Параметр
creationflagsдляPopen, указывающий, что новый процесс не будет наследовать консоль родительского процесса. Это значение нельзя использовать вместе с CREATE_NEW_CONSOLE.Добавлено в версии 3.7.
-
subprocess.CREATE_DEFAULT_ERROR_MODE -
Параметр
creationflagsдляPopen, указывающий, что новый процесс не наследует режим обработки ошибок вызывающего процесса. Вместо этого новый процесс получает режим обработки ошибок по умолчанию. Эта возможность особенно полезна для многопоточных приложений-оболочек, работающих с отключённой обработкой критических ошибок.Добавлено в версии 3.7.
-
subprocess.CREATE_BREAKAWAY_FROM_JOB -
Параметр
creationflagsдля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.
Изменено в версии 3.12: Изменён порядок поиска оболочки Windows для
shell=True. Текущий каталог и%PATH%заменены на%COMSPEC%и%SystemRoot%\System32\cmd.exe. В результате больше не получится запустить вредоносную программу с именемcmd.exe, помещённую в текущий каталог.
-
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.
Изменено в версии 3.12: Изменён порядок поиска оболочки Windows для
shell=True. Текущий каталог и%PATH%заменены на%COMSPEC%и%SystemRoot%\System32\cmd.exe. В результате больше не получится запустить вредоносную программу с именемcmd.exe, помещённую в текущий каталог.
-
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(): передача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.
Изменено в версии 3.12: Изменён порядок поиска оболочки Windows для
shell=True. Текущий каталог и%PATH%заменены на%COMSPEC%и%SystemRoot%\System32\cmd.exe. В результате больше не получится запустить вредоносную программу с именемcmd.exe, помещённую в текущий каталог.
Замена старых функций модулем 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()
Обработка кода возврата соответствует следующему:
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")
Устаревшие функции вызова оболочки
Этот модуль также предоставляет следующие устаревшие функции из модуля commands версии 2.x. Эти операции неявно вызывают системную оболочку, и для них не действуют описанные выше гарантии безопасности и единообразной обработки исключений.
-
subprocess.getstatusoutput(cmd, *, encoding=None, errors=None) -
Возвращает
(exitcode, output)выполнения cmd в оболочке.Выполняет строку cmd в оболочке с помощью
check_output()и возвращает кортеж из двух элементов(exitcode, output). Для декодирования вывода используются encoding и errors; дополнительные сведения см. в примечаниях к разделу Часто используемые аргументы.Завершающий символ новой строки удаляется из вывода. Код завершения команды можно интерпретировать как код возврата подпроцесса. Пример:
>>> 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, '')Доступность: Unix, Windows.
Изменено в версии 3.3.4: Добавлена поддержка Windows.
Теперь функция возвращает (exitcode, output) вместо (status, output), как это было в Python 3.3.3 и более ранних версиях. Значение exitcode совпадает со значением
returncode.Изменено в версии 3.11: Добавлены параметры encoding и errors.
-
subprocess.getoutput(cmd, *, encoding=None, errors=None) -
Возвращает вывод (stdout и stderr) выполнения cmd в оболочке.
Аналогично
getstatusoutput(), но код завершения игнорируется, а возвращаемое значение представляет собой строку с выводом команды. Пример:>>> subprocess.getoutput('ls /bin/ls') '/bin/ls'Доступность: Unix, Windows.
Изменено в версии 3.3.4: Добавлена поддержка Windows.
Изменено в версии 3.11: Добавлены параметры encoding и errors.
Примечания
Поведение при превышении времени ожидания
При использовании параметра timeout в таких функциях, как run(), Popen.wait() или Popen.communicate(), следует учитывать следующее:
- Задержка при создании процесса: Во многих API платформы невозможно прервать само создание процесса. Это означает, что даже при указании времени ожидания исключение о его превышении не обязательно будет получено раньше, чем завершится создание процесса.
-
Чрезвычайно малые значения времени ожидания: Если задать очень малое время ожидания (например, несколько миллисекунд), исключение
TimeoutExpiredможет возникнуть почти сразу, поскольку создание процесса и планирование системой неизбежно требуют времени.
Преобразование последовательности аргументов в строку в Windows
В Windows последовательность args преобразуется в строку, которую можно разобрать по следующим правилам (они соответствуют правилам среды выполнения MS C):
- Аргументы разделяются пробельными символами: пробелом или табуляцией.
- Строка, заключённая в двойные кавычки, интерпретируется как один аргумент независимо от содержащихся в ней пробельных символов. Строку в кавычках можно включить в аргумент.
- Двойная кавычка, перед которой стоит обратная косая черта, интерпретируется как буквальная двойная кавычка.
- Обратные косые черты интерпретируются буквально, если только непосредственно за ними не следует двойная кавычка.
- Если непосредственно перед двойной кавычкой стоят обратные косые черты, каждая пара обратных косых черт интерпретируется как буквальная обратная косая черта. Если число обратных косых черт нечётное, последняя обратная косая черта экранирует следующую двойную кавычку, как описано в правиле 3.
См. также
-
shlex -
Модуль, предоставляющий функции для разбора и экранирования командных строк.
Отключение использования posix_spawn()
В Linux subprocess по умолчанию при возможности использует внутри системный вызов vfork() вместо fork(). Это значительно повышает производительность.
subprocess._USE_POSIX_SPAWN = False # See CPython issue gh-NNNNNN.
В любой версии Python безопасно установить для этого параметра значение false. В старых или новых версиях, где он не поддерживается, это ни на что не повлияет. Не следует предполагать, что этот атрибут доступен для чтения. Несмотря на название, значение true не означает, что будет использована соответствующая функция, а лишь указывает на такую возможность.
Если вам приходится использовать эти внутренние параметры, сообщайте об ошибках и прикладывайте пример, позволяющий воспроизвести проблему. Добавьте ссылку на сообщение об ошибке в комментарий к коду.
Добавлено в версии 3.8: _USE_POSIX_SPAWN
© 2001 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/library/subprocess.html