Содержание страницы
17.5. subprocess – Управление подпроцессами¶subprocess – Subprocess management
Исходный код: Lib/subprocess.py
Модуль subprocess позволяет создавать новые процессы, подключаться к их каналам ввода/вывода/ошибок и получать их коды возврата. Этот модуль призван заменить несколько более старых модулей и функций:
os.system
os.spawn*
Информация о том, как с помощью модуля subprocess заменить эти модули и функции, приведена в следующих разделах.
См. также
PEP 324 – PEP, предлагающий модуль подпроцесса
17.5.1. Использование модуля subprocess¶Using the subprocess Module
Рекомендуемый способ вызова подпроцессов – использовать функцию run() для всех случаев, с которыми она может справиться. Для более сложных случаев можно напрямую использовать нижележащий интерфейс Popen.
Функция run() была добавлена в Python 3.5; если требуется сохранить
совместимость со старыми версиями, см. раздел Старого высокоуровневого API.
-
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False)¶ Выполняет команду, описанную аргументом args. Ожидает завершения команды и возвращает экземпляр
CompletedProcess.Аргументы, показанные выше, – лишь наиболее распространённые; они описаны ниже в разделе Часто используемые аргументы (отсюда использование только именованных аргументов в сокращённой сигнатуре). Полная сигнатура функции в основном совпадает с сигнатурой конструктора
Popen– за исключением timeout, input и check; все остальные аргументы этой функции передаются этому интерфейсу.По умолчанию stdout и stderr не захватываются. Чтобы это сделать, передайте
PIPEдля аргументов stdout и/или stderr.Аргумент timeout передаётся в
Popen.communicate(). Если время ожидания истекает, дочерний процесс будет завершён, и он будет ожидаться. ИсключениеTimeoutExpiredбудет возбуждено повторно после завершения дочернего процесса.Аргумент input передаётся в
Popen.communicate(), а через него – в stdin подпроцесса. Если он используется, то должен представлять собой последовательность байтов или строку, еслиuniversal_newlines=True. При использовании внутренний объектPopenавтоматически создаётся сstdin=PIPE, и аргумент stdin не может быть использован.Если check истинно и процесс завершается с ненулевым кодом возврата, будет возбуждено исключение
CalledProcessError. Атрибуты этого исключения содержат аргументы, код возврата, а также stdout и stderr, если они были захвачены.Примеры:
>>> subprocess.run(["ls", "-l"]) # не захватывает вывод CompletedProcess(args=['ls', '-l'], returncode=0) >>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 >>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE) 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')
Новое в версии 3.5.
-
class
subprocess.CompletedProcess¶ Возвращаемое значение
run(), представляющее завершившийся процесс.-
args¶ Аргументы, использованные для запуска процесса. Это может быть список или строка.
-
returncode¶ Статус выхода дочернего процесса. Обычно статус выхода 0 указывает на успешное завершение.
Отрицательное значение
-Nуказывает, что дочерний процесс был завершён сигналомN(только POSIX).
-
stdout¶ Захваченный stdout дочернего процесса. Последовательность байтов или строка, если
run()был вызван сuniversal_newlines=True.None, если stdout не был захвачен.Если процесс был запущен с
stderr=subprocess.STDOUT, stdout и stderr будут объединены в этом атрибуте, аstderrбудет равноNone.
-
stderr¶ Захваченный stderr дочернего процесса. Последовательность байтов или строка, если
run()был вызван сuniversal_newlines=True.None, если stderr не был захвачен.
-
check_returncode()¶ Если
returncodeненулевой, возбуждаетсяCalledProcessError.
Новое в версии 3.5.
-
-
subprocess.DEVNULL¶ Специальное значение, которое можно использовать в качестве аргумента stdin, stdout или stderr для
Popenи указывает, что будет использоваться специальный файлos.devnull.Новое в версии 3.3.
-
subprocess.PIPE¶ Специальное значение, которое можно использовать в качестве аргумента stdin, stdout или stderr для
Popenи указывает, что должен быть открыт канал (pipe) для стандартного потока. Наиболее полезен сPopen.communicate().
-
subprocess.STDOUT¶ Специальное значение, которое можно использовать в качестве аргумента stderr для
Popenи указывает, что стандартный поток ошибок должен направляться в тот же дескриптор, что и стандартный вывод.
-
exception
subprocess.SubprocessError¶ Базовый класс для всех остальных исключений из этого модуля.
Новое в версии 3.3.
-
exception
subprocess.TimeoutExpired¶ Подкласс
SubprocessError, возбуждается при истечении тайм-аута во время ожидания дочернего процесса.-
cmd¶ Команда, которая использовалась для запуска дочернего процесса.
-
timeout¶ Тайм-аут в секундах.
-
output¶ Вывод дочернего процесса, если он был захвачен с помощью
run()илиcheck_output(). В противном случаеNone.
-
stderr¶ Вывод stderr дочернего процесса, если он был захвачен с помощью
run(). В противном случае –None.
Новое в версии 3.3.
Изменено в версии 3.5: добавлены атрибуты stdout и stderr
-
-
exception
subprocess.CalledProcessError¶ Подкласс
SubprocessError, вызываемый, когда процесс, запущенный черезcheck_call()илиcheck_output(), возвращает ненулевой код завершения.-
returncode¶ Статус выхода дочернего процесса. Если процесс завершился из-за сигнала, это будет отрицательный номер сигнала.
-
cmd¶ Команда, которая использовалась для запуска дочернего процесса.
-
output¶ Вывод дочернего процесса, если он был захвачен с помощью
run()илиcheck_output(). В противном случаеNone.
-
stderr¶ Вывод stderr дочернего процесса, если он был захвачен с помощью
run(). В противном случае –None.
Изменено в версии 3.5: добавлены атрибуты stdout и stderr
-
17.5.1.1. Часто используемые аргументы¶Frequently Used Arguments
Чтобы поддерживать широкий спектр сценариев использования, конструктор Popen (и
удобные функции) принимает большое количество необязательных аргументов. Для
большинства типичных случаев многие из этих аргументов можно безопасно оставить
со значениями по умолчанию. Наиболее часто требуемые аргументы:
args обязателен для всех вызовов и должен быть строкой или последовательностью аргументов программы. Как правило, предпочтительнее передавать последовательность аргументов, так как это позволяет модулю позаботиться о любом необходимом экранировании и кавычках аргументов (например, для пробелов в именах файлов). Если передаётся одна строка, то либо shell должен быть
True(см. ниже), либо строка должна просто указывать имя программы для запуска без указания каких-либо аргументов.stdin, stdout и stderr задают файловые дескрипторы стандартного ввода, стандартного вывода и стандартного вывода ошибок выполняемой программы соответственно. Допустимые значения:
PIPE,DEVNULL, существующий файловый дескриптор (положительное целое число), существующий файловый объект иNone.PIPEуказывает, что должен быть создан новый канал к дочернему процессу.DEVNULLуказывает, что будет использоваться специальный файлos.devnull. При настройках по умолчанию (None) перенаправление не выполняется; файловые дескрипторы дочернего процесса наследуются от родительского. Кроме того, stderr может бытьSTDOUT, что означает, что данные stderr дочернего процесса должны быть направлены в тот же файловый дескриптор, что и для stdout.Если universal_newlines имеет значение
False, файловые объекты stdin, stdout и stderr будут открыты как бинарные потоки, и преобразование концов строк не выполняется.Если universal_newlines имеет значение
True, эти файловые объекты будут открыты как текстовые потоки в режиме универсальные новые строки с использованием кодировки, возвращаемойlocale.getpreferredencoding(False). Для stdin символы концов строк'\n'во входных данных будут преобразованы в разделитель строк по умолчаниюos.linesep. Для stdout и stderr все концы строк в выходных данных будут преобразованы в'\n'. Дополнительную информацию см. в документации классаio.TextIOWrapper, когда аргумент newline его конструктора равенNone.Примечание
Атрибут 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.
17.5.1.2. Конструктор Popen¶Popen Constructor
Создание и управление базовыми процессами в этом модуле осуществляется
классом 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=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=())¶ Запускает дочернюю программу в новом процессе. На POSIX класс использует поведение, подобное
os.execvp(), для выполнения дочерней программы. На Windows класс использует функцию WindowsCreateProcess(). АргументыPopenописаны ниже.args должен быть последовательностью аргументов программы или отдельной строкой. По умолчанию, если args является последовательностью, исполняемая программа – это первый элемент в args. Если args – строка, интерпретация зависит от платформы и описана ниже. Дополнительные отличия от поведения по умолчанию см. в аргументах shell и executable. Если не указано иное, рекомендуется передавать args как последовательность.
На POSIX, если args – строка, она интерпретируется как имя или путь к программе для запуска. Однако это можно сделать только в том случае, если программе не передаются аргументы.
Примечание
shlex.split()может быть полезен при определении правильной токенизации для args, особенно в сложных случаях:>>> import shlex, subprocess >>> command_line = input() /bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'" >>> args = shlex.split(command_line) >>> print(args) ['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"] >>> p = subprocess.Popen(args) # Успешно!
Обратите внимание, что опции (такие как -input) и аргументы (такие как eggs.txt), разделённые пробелами в оболочке, помещаются в отдельные элементы списка, в то время как аргументы, требующие кавычек или обратной косой черты в оболочке (например, имена файлов, содержащие пробелы, или команда echo, показанная выше), являются отдельными элементами списка.
На Windows, если args – последовательность, она будет преобразована в строку способом, описанным в разделе Преобразование последовательности аргументов в строку на Windows. Это связано с тем, что базовая функция
CreateProcess()работает со строками.Аргумент 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.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() в дочернем процессе.
Если close_fds равно True, все файловые дескрипторы, кроме
0,1и2, будут закрыты перед выполнением дочернего процесса (только POSIX). Значение по умолчанию зависит от платформы: всегда True на POSIX. На Windows оно равно True, когда stdin/stdout/stderr равныNone, иначе False. На Windows, если close_fds равно True, то дочерний процесс не унаследует ни один дескриптор. Обратите внимание, что в Windows нельзя установить close_fds в True и одновременно перенаправлять стандартные дескрипторы, задавая stdin, stdout или stderr.Изменено в версии 3.2: Значение по умолчанию для close_fds было изменено с
Falseна то, что описано выше.pass_fds – необязательная последовательность файловых дескрипторов, которые должны оставаться открытыми между родительским и дочерним процессами. Указание любого pass_fds принуждает close_fds принимать значение
True. (Только POSIX)Новое в версии 3.2: Добавлен параметр pass_fds.
Если cwd не равно
None, функция меняет рабочий каталог на cwd перед запуском дочернего процесса. В частности, функция ищет executable (или первый элемент в args) относительно cwd, если путь к исполняемому файлу является относительным.Если restore_signals равен true (по умолчанию), все сигналы, которые Python установил в SIG_IGN, восстанавливаются в SIG_DFL в дочернем процессе перед exec. В настоящее время это включает сигналы SIGPIPE, SIGXFZ и SIGXFSZ. (Только POSIX)
Изменено в версии 3.2: Добавлен restore_signals.
Если start_new_session равен true, системный вызов setsid() будет выполнен в дочернем процессе перед запуском подпроцесса. (только POSIX)
Изменено в версии 3.2: добавлен start_new_session.
Если env не равен
None, он должен быть отображением (mapping), определяющим переменные окружения для нового процесса; они используются вместо поведения по умолчанию, заключающегося в наследовании окружения текущего процесса.Примечание
Если указано, env должен предоставить все переменные, необходимые для выполнения программы. В Windows для запуска сборки side-by-side указанный env должен включать корректный
SystemRoot.Если universal_newlines имеет значение
True, файловые объекты stdin, stdout и stderr открываются как текстовые потоки в режиме универсальных новых строк, как описано выше в разделе Часто используемые аргументы, в противном случае они открываются как бинарные потоки.Если задан, startupinfo будет объектом
STARTUPINFO, который передаётся нижележащей функцииCreateProcess. creationflags, если задан, может бытьCREATE_NEW_CONSOLEилиCREATE_NEW_PROCESS_GROUP(только Windows).Объекты Popen поддерживаются как менеджеры контекста через оператор
with: при выходе стандартные файловые дескрипторы закрываются, и процесс ожидается.with Popen(["ifconfig"], stdout=PIPE) as proc: log.write(proc.stdout.read())
Изменено в версии 3.2: добавлена поддержка менеджера контекста.
17.5.1.3. Исключения¶Exceptions
Исключения, возникающие в дочернем процессе до начала выполнения новой программы,
будут повторно возбуждены в родительском процессе. Кроме того, объект исключения
будет иметь дополнительный атрибут с именем child_traceback, который представляет собой строку,
содержащую информацию о трассировке с точки зрения дочернего процесса.
Наиболее часто вызываемое исключение – OSError. Оно возникает, например, при попытке выполнить несуществующий файл. Приложения должны быть готовы к исключениям OSError.
ValueError будет вызван, если Popen вызвана с недопустимыми аргументами.
check_call() и check_output() вызовут CalledProcessError, если вызванный процесс вернёт ненулевой код возврата.
Все функции и методы, которые принимают параметр тайм-аут, например
call() и Popen.communicate(), будут возбуждать исключение TimeoutExpired, если
тайм-аут истекает до завершения процесса.
Все исключения, определённые в этом модуле, наследуются от SubprocessError.
Новое в версии 3.3: добавлен базовый класс
SubprocessError.
17.5.2. Рекомендации по безопасности¶Security Considerations
В отличие от некоторых других функций popen, данная реализация никогда не вызывает системную оболочку неявно. Это означает, что все символы, включая метасимволы оболочки, можно безопасно передавать дочерним процессам. Если оболочка вызывается явно через shell=True, приложение должно само позаботиться о том, чтобы все пробелы и метасимволы были правильно экранированы во избежание уязвимостей внедрения команд оболочки.
При использовании shell=True функция shlex.quote() может быть
использована для правильного экранирования пробелов и метасимволов оболочки в строках,
которые будут использоваться для построения команд оболочки.
17.5.3. Объекты Popen¶Popen Objects
Экземпляры класса Popen имеют следующие методы:
-
Popen.poll()¶ Проверяет, завершён ли дочерний процесс. Устанавливает и возвращает атрибут
returncode.
-
Popen.wait(timeout=None)¶ Ожидает завершения дочернего процесса. Устанавливает и возвращает атрибут
returncode.Если процесс не завершается через тайм-аут секунд, возбуждается исключение
TimeoutExpired. Это исключение можно безопасно перехватить и повторить ожидание.Примечание
Это приведёт к взаимоблокировке при использовании
stdout=PIPEилиstderr=PIPEи когда дочерний процесс порождает достаточно выходных данных в канал, так что он блокируется в ожидании, когда буфер канала ОС примет больше данных. ИспользуйтеPopen.communicate()при работе с каналами, чтобы избежать этого.Примечание
Функция реализована с помощью busy-цикла (неблокирующий вызов и короткие паузы). Используйте модуль
asyncioдля асинхронного ожидания: см.asyncio.create_subprocess_exec.Изменено в версии 3.3: добавлен timeout.
Устарело с версии 3.4: Не используйте параметр endtime. Он был случайно открыт в версии 3.3, но остался недокументированным, так как предполагался приватным для внутреннего использования. Вместо него используйте timeout.
-
Popen.communicate(input=None, timeout=None)¶ Взаимодействует с процессом: отправляет данные в stdin. Читает данные из stdout и stderr, до достижения конца файла. Ожидает завершения процесса. Необязательный аргумент input должен содержать данные для отправки дочернему процессу или
None, если данные не нужно отправлять. Тип input должен быть bytes или, если universal_newlines былоTrue, строкой.communicate()возвращает кортеж(stdout_data, stderr_data). Данные будут в формате bytes или, если universal_newlines былоTrue, строк.Обратите внимание: если вы хотите отправить данные в stdin процесса, необходимо создать объект Popen с
stdin=PIPE. Аналогично, чтобы получить что-то, кромеNone, в результирующем кортеже, нужно также передатьstdout=PIPEи/илиstderr=PIPE.Если процесс не завершится за timeout секунд, будет вызвано исключение
TimeoutExpired. Перехват этого исключения и повторное обращение к обмену данными не приведет к потере вывода.Дочерний процесс не уничтожается по истечении тайм-аута, поэтому для корректной очистки хорошо написанное приложение должно уничтожить дочерний процесс и завершить обмен данными:
proc = subprocess.Popen(...) try: outs, errs = proc.communicate(timeout=15) except TimeoutExpired: proc.kill() outs, errs = proc.communicate()
Примечание
Прочитанные данные буферизуются в памяти, поэтому не используйте этот метод, если размер данных велик или неограничен.
Изменено в версии 3.3: добавлен timeout.
-
Popen.send_signal(signal)¶ Отправляет сигнал signal дочернему процессу.
Примечание
В Windows SIGTERM является псевдонимом для
terminate(). CTRL_C_EVENT и CTRL_BREAK_EVENT можно отправлять процессам, запущенным с параметром creationflags, включающим CREATE_NEW_PROCESS_GROUP.
-
Popen.terminate()¶ Останавливает дочерний процесс. В ОС POSIX метод отправляет SIGTERM дочернему процессу. В Windows для остановки дочернего процесса вызывается функция Win32 API
TerminateProcess().
-
Popen.kill()¶ Завершает дочерний процесс. В ОС POSIX функция отправляет SIGKILL дочернему процессу. В Windows
kill()является псевдонимом дляterminate().
Также доступны следующие атрибуты:
-
Popen.args¶ Аргумент args в том виде, в котором он был передан в
Popen– последовательность аргументов программы или одна строка.Новое в версии 3.3.
-
Popen.stdin¶ Если аргумент stdin был
PIPE, этот атрибут представляет собой записываемый объект потока, возвращаемыйopen(). Если аргумент universal_newlines былTrue, поток является текстовым, в противном случае – байтовым потоком. Если аргумент stdin не былPIPE, этот атрибут равенNone.
-
Popen.stdout¶ Если аргумент stdout был
PIPE, этот атрибут представляет собой читаемый объект потока, возвращаемыйopen(). Чтение из потока предоставляет вывод дочернего процесса. Если аргумент universal_newlines былTrue, поток является текстовым, в противном случае – байтовым потоком. Если аргумент stdout не былPIPE, этот атрибут равенNone.
-
Popen.stderr¶ Если аргумент stderr был
PIPE, этот атрибут представляет собой читаемый объект потока, возвращаемыйopen(). Чтение из потока предоставляет вывод ошибок дочернего процесса. Если аргумент 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).
17.5.4. Вспомогательные классы Popen для Windows¶Windows Popen Helpers
Класс STARTUPINFO и следующие константы доступны только
в Windows.
-
class
subprocess.STARTUPINFO¶ Частичная поддержка структуры Windows STARTUPINFO используется для создания
Popen.-
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.
-
17.5.4.1. Константы¶Constants
Модуль 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¶ Параметр
Popencreationflags, указывающий, что будет создана новая группа процессов. Этот флаг необходим для использованияos.kill()в подпроцессе.Этот флаг игнорируется, если указан
CREATE_NEW_CONSOLE.
17.5.5. Старый высокоуровневый API¶Older high-level API
До Python 3.5 эти три функции представляли собой высокоуровневый API для
subprocess. Теперь во многих случаях можно использовать run(), но значительная часть существующего кода
по-прежнему вызывает эти функции.
-
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)¶ Запускает команду, описанную параметром args. Ожидает завершения команды и затем возвращает атрибут
returncode.Это эквивалентно:
run(...).returncode
(за исключением того, что параметры input и check не поддерживаются)
Показанные выше аргументы – лишь самые распространённые. Полная сигнатура функции в основном совпадает с сигнатурой конструктора
Popen– эта функция передаёт все переданные аргументы, кроме timeout, напрямую в этот интерфейс.Примечание
Не используйте
stdout=PIPEилиstderr=PIPEс этой функцией. Дочерний процесс будет заблокирован, если он выдаст в канал достаточно данных, чтобы заполнить буфер канала ОС, поскольку каналы не читаются.Изменено в версии 3.3: добавлен timeout.
-
subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)¶ Выполняет команду с аргументами. Ожидает завершения команды. Если код возврата равен нулю, возвращает результат, иначе вызывает
CalledProcessError. ОбъектCalledProcessErrorбудет содержать код возврата в атрибутеreturncode.Это эквивалентно:
run(..., check=True)
(за исключением того, что параметр input не поддерживается)
Показанные выше аргументы – лишь самые распространённые. Полная сигнатура функции в основном совпадает с сигнатурой конструктора
Popen– эта функция передаёт все переданные аргументы, кроме timeout, напрямую в этот интерфейс.Примечание
Не используйте
stdout=PIPEилиstderr=PIPEс этой функцией. Дочерний процесс будет заблокирован, если он выдаст в канал достаточно данных, чтобы заполнить буфер канала ОС, поскольку каналы не читаются.Изменено в версии 3.3: добавлен timeout.
-
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None)¶ Выполняет команду с аргументами и возвращает её вывод.
Если код возврата был ненулевым, возбуждается исключение
CalledProcessError. ОбъектCalledProcessErrorбудет содержать код возврата в атрибутеreturncode, а вывод – в атрибутеoutput.Это эквивалентно:
run(..., check=True, stdout=PIPE).stdout
Показанные выше аргументы – лишь самые распространённые. Полная сигнатура функции в основном та же, что и у
run()– большинство аргументов передаются напрямую в этот интерфейс. Однако явная передачаinput=Noneдля наследования дескриптора стандартного ввода родительского процесса не поддерживается.По умолчанию эта функция возвращает данные в виде закодированных байтов. Фактическая кодировка выходных данных может зависеть от вызываемой команды, поэтому декодирование в текст часто приходится выполнять на уровне приложения.
Это поведение можно переопределить, установив universal_newlines в
True, как описано выше в разделе Часто используемые аргументы.Чтобы также захватывать стандартный поток ошибок в результате, используйте
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.
17.5.6. Замена старых функций модулем subprocess¶Replacing Older Functions with the subprocess Module
В этом разделе «a становится b» означает, что b можно использовать как замену для a.
Примечание
Все функции вида «a» в этом разделе завершаются ошибкой (более или менее) молча, если выполняемая программа не найдена; замены «b» вместо этого возбуждают OSError.
Кроме того, замены, использующие check_output(), будут завершаться ошибкой с CalledProcessError, если запрошенная операция возвращает ненулевой код возврата. Вывод по-прежнему доступен как атрибут output возбуждённого исключения.
В следующих примерах предполагается, что соответствующие функции уже импортированы из модуля subprocess.
17.5.6.1. Замена обратных кавычек оболочки /bin/sh¶Replacing /bin/sh shell backquote
output=`mycmd myarg`
становится:
output = check_output(["mycmd", "myarg"])
17.5.6.2. Замена конвейера оболочки¶Replacing shell pipeline
output=`dmesg | grep hda`
становится:
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close() # Разрешить p1 получать SIGPIPE, если p2 завершается.
output = p2.communicate()[0]
Вызов p1.stdout.close() после запуска p2 важен для того, чтобы p1 получил SIGPIPE, если p2 завершится раньше p1.
В качестве альтернативы, для доверенного ввода можно по-прежнему напрямую использовать встроенную поддержку конвейеров оболочки:
output=`dmesg | grep hda`
становится:
output=check_output("dmesg | grep hda", shell=True)
17.5.6.3. Замена os.system()¶Replacing os.system()
sts = os.system("mycmd" + " myarg")
# становится
sts = call("mycmd" + " myarg", shell=True)
Примечания:
- Вызов программы через оболочку обычно не требуется.
Более реалистичный пример выглядит так:
try:
retcode = call("mycmd" + " myarg", shell=True)
if retcode < 0:
print("Child was terminated by signal", -retcode, file=sys.stderr)
else:
print("Child returned", retcode, file=sys.stderr)
except OSError as e:
print("Execution failed:", e, file=sys.stderr)
17.5.6.4. Замена семейства os.spawn¶Replacing the os.spawn family
Пример 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"})
17.5.6.5. Замена os.popen(), os.popen2(), os.popen3()¶Replacing 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")
17.5.6.6. Замена функций из модуля popen2¶Replacing functions from the popen2 module
Примечание
Если аргумент 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.
17.5.7. Устаревшие функции вызова оболочки¶Legacy Shell Invocation Functions
Этот модуль также предоставляет следующие устаревшие функции из модуля commands версии 2.x. Эти операции неявно вызывают системную оболочку, и ни одно из описанных выше гарантий безопасности и согласованности обработки исключений не действует для этих функций.
-
subprocess.getstatusoutput(cmd)¶ Возвращает
(status, output)выполнения cmd в оболочке.Выполняет строку cmd в оболочке с
Popen.check_output()и возвращает кортеж из двух элементов(status, output). Используется режим универсальных новых строк; см. примечания к Часто используемые аргументы для подробностей.Конечный символ новой строки удаляется из вывода. Статус выхода команды можно интерпретировать в соответствии с правилами для функции C
wait(). Пример:>>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') >>> subprocess.getstatusoutput('cat /bin/junk') (256, 'cat: /bin/junk: No such file or directory') >>> subprocess.getstatusoutput('/bin/junk') (256, 'sh: /bin/junk: not found')
Доступность: POSIX и Windows
Изменено в версии 3.3.4: Добавлена поддержка Windows
-
subprocess.getoutput(cmd)¶ Возвращает вывод (stdout и stderr) выполнения cmd в оболочке.
Как
getstatusoutput(), за исключением того, что статус выхода игнорируется, а возвращаемое значение – строка, содержащая вывод команды. Пример:>>> subprocess.getoutput('ls /bin/ls') '/bin/ls'
Доступность: POSIX и Windows
Изменено в версии 3.3.4: Добавлена поддержка Windows
17.5.8. Примечания¶Notes
17.5.8.1. Преобразование последовательности аргументов в строку в Windows¶Converting an argument sequence to a string on Windows
В Windows последовательность args преобразуется в строку, которая может быть разобрана с помощью следующих правил (которые соответствуют правилам, используемым в MS C runtime):
- Аргументы разделяются пробельными символами, то есть пробелом или табуляцией.
- Строка, заключённая в двойные кавычки, интерпретируется как один аргумент, независимо от пробельных символов внутри неё. Строка в кавычках может быть встроена в аргумент.
- Двойная кавычка, перед которой стоит обратная косая черта, интерпретируется как литеральная двойная кавычка.
- Обратные косые черты интерпретируются буквально, если только они не стоят непосредственно перед двойной кавычкой.
- Если обратные косые черты стоят непосредственно перед двойной кавычкой, каждая пара обратных косых черт интерпретируется как литеральная обратная косая черта. Если количество обратных косых черт нечётное, последняя обратная косая черта экранирует следующую за ней двойную кавычку, как описано в правиле 3.
См. также
shlex- Модуль, предоставляющий функцию для разбора и экранирования командных строк.