subprocess — Управление дочерними процессами
Исходный код: Lib/subprocess.py
Модуль subprocess позволяет запускать новые процессы, подключаться к их каналам ввода/вывода/ошибок и получать их коды возврата. Данный модуль предназначен для замены нескольких более старых модулей и функций:
os.system os.spawn*
Информация о том, как модуль subprocess может быть использован для замены этих модулей и функций, приведена в следующих разделах.
См. также
PEP 324 — PEP, предлагающий модуль subprocess
17.5.1. Использование модуля subprocess
Рекомендуемый подход к вызову дочерних процессов — использование функции run() для всех случаев, когда она подходит. Для более сложных случаев можно напрямую использовать базовый интерфейс Popen.
Функция run() была добавлена в Python 3.5; если вам нужно сохранить совместимость со старыми версиями, обратитесь к разделу Старый API высокого уровня.
-
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, env=None) -
Запустить команду, описанную в args. Дождаться завершения команды, а затем вернуть экземпляр
CompletedProcess.Перечисленные выше аргументы — лишь наиболее распространённые, подробно описанные ниже в разделе Часто используемые аргументы (отсюда использование обозначения только ключевых слов в сокращённой сигнатуре). Полная сигнатура функции в основном совпадает с сигнатурой конструктора
Popen— за исключением timeout, input и check, все аргументы этой функции передаются этому интерфейсу.По умолчанию stdout и stderr не捕获. Для этого передайте
PIPEдля аргументов stdout и/или stderr.Аргумент timeout передаётся в
Popen.communicate(). Если тайм-аут истекает, дочерний процесс будет убит и дождаться его завершения. ИсключениеTimeoutExpiredбудет повторно поднято после завершения дочернего процесса.Аргумент input передаётся в
Popen.communicate(), а значит, и в стандартный ввод дочернего процесса. Если используется, он должен быть последовательностью байтов или строкой, если указаны encoding или errors, или universal_newlines истинно. В этом случае внутренний объектPopenавтоматически создаётся сstdin=PIPE, и аргумент stdin также не может быть использован.Если check истинно, и процесс завершается с кодом возврата, отличным от нуля, будет возбуждено исключение
CalledProcessError. Атрибуты этого исключения содержат аргументы, код возврата и stdout и stderr, если они были захвачены.Если указаны encoding или errors, или universal_newlines истинно, файлы для stdin, stdout и stderr открываются в текстовом режиме с указанным encoding и errors или по умолчанию
io.TextIOWrapper. В противном случае файлы открываются в двоичном режиме.Если env не
None, он должен быть отображением, определяющим переменные среды для нового процесса; они используются вместо поведения по умолчанию, которое наследует среду текущего процесса. Он передаётся напрямую вPopen.Примеры:
>>> subprocess.run(["ls", "-l"]) # doesn't capture output CompletedProcess(args=['ls', '-l'], returncode=0) >>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 >>> subprocess.run(["ls", "-l", "/dev/null"], 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.
Изменено в версии 3.6: Добавлены параметры encoding и errors
-
class subprocess.CompletedProcess -
Возвращаемое значение функции
run(), представляющее собой завершённый процесс.-
args -
Аргументы, использованные для запуска процесса. Может быть списком или строкой.
-
returncode -
Код возврата дочернего процесса. Обычно код возврата 0 означает успешное выполнение.
Отрицательное значение
-Nуказывает, что дочерний процесс был завершён сигналомN(только POSIX).
-
stdout -
Захваченный stdout дочернего процесса. Последовательность байтов или строка, если
run()вызывался с кодировкой или ошибками.Noneесли stdout не был захвачен.Если процесс запускался с
stderr=subprocess.STDOUT, stdout и stderr будут объединены в этом атрибуте, аstderrбудетNone.
-
stderr -
Захваченный stderr дочернего процесса. Последовательность байтов или строка, если
run()вызывался с кодировкой или ошибками.Noneесли stderr не был захвачен.
-
check_returncode() -
Если
returncodeне равен нулю, возбудитеCalledProcessError.
Добавлена в версии 3.5.
-
-
subprocess.DEVNULL -
Специальное значение, которое может использоваться в качестве аргумента stdin, stdout или stderr для
Popenи указывает, что будет использован специальный файлos.devnull.Добавлена в версии 3.3.
-
subprocess.PIPE -
Специальное значение, которое может использоваться в качестве аргумента stdin, stdout или stderr для
Popenи указывает на то, что должен быть открыт канал к стандартному потоку. Наиболее полезно сPopen.communicate().
-
subprocess.STDOUT -
Специальное значение, которое может использоваться в качестве аргумента stderr для
Popenи указывает, что стандартная ошибка должна быть направлена в тот же обработчик, что и стандартный вывод.
-
exception subprocess.SubprocessError -
Базовый класс для всех остальных исключений из этого модуля.
Добавлена в версии 3.3.
-
exception subprocess.TimeoutExpired -
Подкласс
SubprocessError, возбуждаемый, когда тайм-аут истекает при ожидании дочернего процесса.-
cmd -
Команда, которая использовалась для запуска дочернего процесса.
-
timeout -
Тайм-аут в секундах.
-
output -
Вывод дочернего процесса, если он был захвачен функцией
run()илиcheck_output(). В противном случаеNone.
-
stdout -
Псевдоним для output для симметрии с
stderr.
-
stderr -
Вывод stderr дочернего процесса, если он был захвачен
run(). В противном случаеNone.
Добавлена в версии 3.3.
Изменено в версии 3.5: Добавлены атрибуты stdout и stderr
-
-
exception subprocess.CalledProcessError -
Подкласс
SubprocessError, генерируется, когда процесс, запущенный с помощьюcheck_call()илиcheck_output(), возвращает ненулевой код выхода.-
returncode -
Код выхода дочернего процесса. Если процесс завершился из-за сигнала, это будет отрицательное значение номера сигнала.
-
cmd -
Команда, использованная для запуска дочернего процесса.
-
output -
Вывод дочернего процесса, если он был перехвачен
run()илиcheck_output(). В противном случае,None.
-
stdout -
Псевдоним для output, для симметрии с
stderr.
-
stderr -
Вывод stderr дочернего процесса, если он был перехвачен
run(). В противном случае,None.
Изменено в версии 3.5: Добавлены атрибуты stdout и stderr
-
17.5.1.1. Часто используемые аргументы
Для поддержки широкого спектра случаев использования конструктор Popen (и вспомогательные функции) принимают большое количество необязательных аргументов. Для большинства типичных случаев использования многие из этих аргументов можно безопасно оставить со значениями по умолчанию. Аргументы, которые чаще всего необходимы, это:
args требуется для всех вызовов и должен быть строкой или последовательностью аргументов программы. Использование последовательности аргументов обычно предпочтительнее, так как это позволяет модулю позаботиться об необходимой экранизации и обработке аргументов (например, для поддержки пробелов в именах файлов). Если передаётся одна строка, то shell должен быть True (см. ниже), или же строка должна просто указывать имя программы для выполнения без указания аргументов.
stdin, stdout и stderr соответственно указывают стандартный ввод, стандартный вывод и стандартную ошибку исполняемой программы. Допустимые значения — PIPE, DEVNULL, существующий дескриптор файла (положительное целое число), существующий объект файла и None. PIPE означает, что должен быть создан новый канал для дочернего процесса. DEVNULL означает, что будет использован специальный файл os.devnull. При значениях по умолчанию None, перенаправления не будет; дескрипторы файлов дочернего процесса будут унаследованы от родительского. Кроме того, stderr может быть STDOUT, что указывает на то, что данные stderr дочернего процесса должны быть перехвачены в тот же дескриптор файла, что и stdout.
Если указаны encoding или errors, или 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.
Примечание
Атрибут 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. Он предлагает большую гибкость, позволяя разработчикам обрабатывать менее распространённые случаи, не покрытые вспомогательными функциями.
-
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=(), *, encoding=None, errors=None) -
Выполнить дочернюю программу в новом процессе. В 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) # Success!
Обратите особое внимание на то, что опции (например, -input) и аргументы (например, eggs.txt), разделённые пробелами в оболочке, попадают в отдельные элементы списка, а аргументы, которые требуют кавычек или обратного слэша при использовании в оболочке (например, имена файлов, содержащие пробелы или команда echo, показанная выше), являются отдельными элементами списка.
В Windows, если args является последовательностью, она будет преобразована в строку способом, описанным в Преобразование последовательности аргументов в строку в Windows. Это происходит потому, что базовая функция
CreateProcess()работает со строками.Аргумент shell (который по умолчанию
False) определяет, использовать ли оболочку в качестве программы для выполнения. Если shellTrue, рекомендуется передавать 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 перед выполнением дочернего процесса. cwd может бытьstrи объектом, похожим на путь. В частности, функция ищет executable (или первый элемент в args) относительно cwd, если путь к исполняемому файлу — относительный.Изменено в версии 3.6: Параметр 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, это должна быть карта, определяющая переменные среды для нового процесса; они используются вместо поведения по умолчанию — наследования текущей среды процесса.Примечание
Если указан, env должен предоставлять любые переменные, необходимые для выполнения программы. В Windows, для работы с параллельными сборками указанный env **должен** содержать корректную
SystemRoot. -
Если указаны encoding или errors, объекты файлов stdin, stdout и stderr открываются в текстовом режиме с указанным кодированием и errors, как описано выше в Часто используемые аргументы. Если universal_newlines
True, они открываются в текстовом режиме с кодированием по умолчанию. В противном случае они открываются как двоичные потоки.Введено в версии 3.6: encoding и errors были добавлены.
Если задано 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: Добавлена поддержка менеджера контекста.
Изменено в версии 3.6: Деструктор Popen теперь выводит предупреждение
ResourceWarning, если дочерний процесс всё ещё выполняется.
17.5.1.3. Исключения
Исключения, поднятые в дочернем процессе до запуска новой программы, будут повторно подняты в родительском. Кроме того, у объекта исключения будет дополнительный атрибут, называемый child_traceback, представляющий собой строку с информацией о трассировке стека с точки зрения дочернего процесса.
Наиболее распространённое исключение — OSError. Это происходит, например, при попытке выполнить несуществующий файл. Приложения должны быть готовы к исключениям OSError.
Исключение ValueError будет поднято, если Popen вызывается с некорректными аргументами.
check_call() и check_output() будут поднимать CalledProcessError, если вызываемый процесс возвращает код ошибки, отличный от нуля.
Все функции и методы, которые принимают параметр timeout, такие как call() и Popen.communicate(), будут поднимать TimeoutExpired, если таймаут истечёт до завершения процесса.
Все исключения, определённые в этом модуле, наследуются от SubprocessError.
Введено в версии 3.3: Базовый класс SubprocessError.
17.5.2. Соображения безопасности
В отличие от некоторых других функций popen, эта реализация никогда не будет неявно вызывать системную оболочку. Это означает, что все символы, включая метасимволы оболочки, могут безопасно передаваться дочерним процессам. Если оболочка вызывается явно, посредством shell=True, ответственность за обеспечение правильной цитирования всех пробелов и метасимволов для предотвращения уязвимостей типа «вставка оболочки» лежит на приложении.
При использовании shell=True, функция shlex.quote() может использоваться для правильной экранировки пробелов и метасимволов оболочки в строках, которые будут использоваться для построения команд оболочки.
17.5.3. Объекты Popen
Экземпляры класса Popen имеют следующие методы:
-
Popen.poll() -
Проверяет, завершил ли дочерний процесс работу. Устанавливает и возвращает атрибут
returncode. В противном случае возвращаетNone.
-
Popen.wait(timeout=None) -
Ожидает завершения дочернего процесса. Устанавливает и возвращает атрибут
returncode.Если процесс не завершается через timeout секунд, возникает исключение
TimeoutExpired. Безопасно перехватывать это исключение и повторно пытаться ожидать.Примечание
Это приведёт к тупиковой ситуации при использовании
stdout=PIPEилиstderr=PIPEи дочерний процесс генерирует достаточно вывода в канал, чтобы заблокировать ожидание, пока буфер канала ОС не примет больше данных. ИспользуйтеPopen.communicate()при использовании каналов, чтобы избежать этого.Примечание
Функция реализована с помощью цикла busy loop (неблокирующий вызов и короткие паузы). Для асинхронного ожидания используйте модуль
asyncio: см.asyncio.create_subprocess_exec.Изменено в версии 3.3: Добавлен timeout.
Устарело начиная с версии 3.4: Не используйте параметр endtime. Он был непреднамеренно экспонирован в 3.3, но не был задокументирован, поскольку предполагалось, что он будет закрытым для внутреннего использования. Используйте вместо этого timeout.
-
Popen.communicate(input=None, timeout=None) -
Взаимодействие с процессом: отправка данных в stdin. Чтение данных из stdout и stderr до достижения конца файла. Ожидание завершения процесса. Необязательный аргумент input должен содержать данные, которые будут отправлены в дочерний процесс, или
None, если данные не должны отправляться. Если потоки открыты в текстовом режиме, input должен быть строкой. В противном случае он должен быть байтами.communicate()возвращает кортеж(stdout_data, stderr_data). Данные будут строками, если потоки открыты в текстовом режиме; в противном случае байтами.Обратите внимание, что если вы хотите отправить данные в stdin процесса, вам необходимо создать объект Popen с
stdin=PIPE. Аналогично, чтобы получить что-либо, кромеNoneв кортеже результата, вам нужно указатьstdout=PIPEи/илиstderr=PIPE.Если процесс не завершается через timeout секунд, возникает исключение
TimeoutExpired. Перехват этого исключения и повторная попытка коммуникации не приведут к потере вывода.Дочерний процесс не убивается, если таймаут истекает, поэтому для правильной очистки приложение должно убить дочерний процесс и завершить коммуникацию:
proc = subprocess.Popen(...) try: outs, errs = proc.communicate(timeout=15) except TimeoutExpired: proc.kill() outs, errs = proc.communicate()Примечание
Считанные данные буферизуются в памяти, поэтому не используйте этот метод, если размер данных большой или неограниченный.
Изменено в версии 3.3: Добавлен timeout.
-
Popen.send_signal(signal) -
Отправляет сигнал signal дочернему процессу.
Примечание
В Windows SIGTERM является псевдонимом для
terminate(). CTRL_C_EVENT и CTRL_BREAK_EVENT могут быть отправлены процессам, запущенным с параметром creationflags, включающимCREATE_NEW_PROCESS_GROUP.
-
Popen.terminate() -
Останавливает дочерний процесс. В системах POSIX метод отправляет сигнал SIGTERM дочернему процессу. В Windows вызывается функция Win32 API
TerminateProcess()для остановки дочернего процесса.
-
Popen.kill() -
Убивает дочерний процесс. В системах POSIX функция отправляет сигнал SIGKILL дочернему процессу. В Windows
kill()является псевдонимом дляterminate().
Также доступны следующие атрибуты:
-
Popen.args -
Аргумент args, как он был передан в
Popen– последовательность аргументов программы или же одна строка.Новое в версии 3.3.
-
Popen.stdin -
Если аргумент stdin был
PIPE, этот атрибут — это объект потока для записи, возвращаемый функциейopen(). Если были указаны аргументы encoding или errors или аргумент universal_newlines былTrue, поток является текстовым, в противном случае — байтовым. Если аргумент stdin не былPIPE, этот атрибут —None.
-
Popen.stdout -
Если аргумент stdout был
PIPE, этот атрибут — это объект потока для чтения, возвращаемый функциейopen(). Чтение из потока предоставляет вывод дочернего процесса. Если были указаны аргументы encoding или errors или аргумент universal_newlines былTrue, поток является текстовым, в противном случае — байтовым. Если аргумент stdout не былPIPE, этот атрибут —None.
-
Popen.stderr -
Если аргумент stderr был
PIPE, этот атрибут — это объект потока для чтения, возвращаемый функциейopen(). Чтение из потока предоставляет вывод ошибок дочернего процесса. Если были указаны аргументы encoding или errors или аргумент universal_newlines былTrue, поток является текстовым, в противном случае — байтовым. Если аргумент stderr не былPIPE, этот атрибут —None.
Предупреждение
Используйте communicate() вместо .stdin.write, .stdout.read или .stderr.read, чтобы избежать тупиковых ситуаций из-за заполнения буферов канала операционной системы и блокировки дочернего процесса.
-
Popen.pid -
Идентификатор процесса дочернего процесса.
Обратите внимание, что если вы установили аргумент shell в
True, это идентификатор процесса созданной оболочки.
-
Popen.returncode -
Код возврата дочернего процесса, устанавливаемый методами
poll()иwait()(и косвенно методомcommunicate()). ЗначениеNoneуказывает на то, что процесс еще не завершился.Отрицательное значение
-Nуказывает, что дочерний процесс был завершен сигналомN(только POSIX).
17.5.4. 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. Константы
Модуль subprocess предоставляет следующие константы.
-
subprocess.STD_INPUT_HANDLE -
Устройство стандартного ввода. Изначально — буфер ввода консоли,
CONIN$.
-
subprocess.STD_OUTPUT_HANDLE -
Устройство стандартного вывода. Изначально — буфер активного экрана консоли,
CONOUT$.
-
subprocess.STD_ERROR_HANDLE -
Устройство стандартного вывода ошибок. Изначально — буфер активного экрана консоли,
CONOUT$.
-
subprocess.SW_HIDE -
Скрывает окно. Будет активировано другое окно.
-
subprocess.STARTF_USESTDHANDLES -
Указывает, что атрибуты
STARTUPINFO.hStdInput,STARTUPINFO.hStdOutputиSTARTUPINFO.hStdErrorсодержат дополнительную информацию.
-
subprocess.STARTF_USESHOWWINDOW -
Указывает, что атрибут
STARTUPINFO.wShowWindowсодержит дополнительную информацию.
-
subprocess.CREATE_NEW_CONSOLE -
Новый процесс получает новую консоль, вместо наследования консоли родителя (по умолчанию).
-
subprocess.CREATE_NEW_PROCESS_GROUP -
Параметр
Popenдля указания создания новой группы процессов. Этот флаг необходим для использованияos.kill()на дочернем процессе.Этот флаг игнорируется, если задан
CREATE_NEW_CONSOLE.
17.5.5. Старые высокоуровневые API
До Python 3.5 эти три функции составляли высокоуровневый API для subprocess. Теперь в многих случаях можно использовать run(), но многие существующие кодовые базы используют эти функции.
-
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, 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, cwd=None, 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, cwd=None, encoding=None, errors=None, 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.
Изменено в версии 3.6: Добавлены encoding и errors. Подробнее см.
run().
17.5.6. Замена устаревших функций модулем subprocess
В этом разделе «a становится b» означает, что b может быть использовано в качестве замены для a.
Примечание
Все функции «a» в этом разделе терпят неудачу (более или менее) безмолвно, если не удаётся найти исполняемую программу; замены «b» вместо этого поднимают исключение OSError.
Кроме того, замены, использующие check_output(), завершатся ошибкой с CalledProcessError, если запрошенная операция приводит к ненулевому коду возврата. Вывод по-прежнему доступен в качестве атрибута output поднятого исключения.
В следующих примерах предполагается, что соответствующие функции уже импортированы из модуля subprocess.
17.5.6.1. Замена оболочки /bin/sh обратными кавычками
output=`mycmd myarg`
становится:
output = check_output(["mycmd", "myarg"])
17.5.6.2. Замена конвейера оболочки
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)
17.5.6.3. Замена os.system()
sts = os.system("mycmd" + " myarg")
# becomes
sts = call("mycmd" + " myarg", shell=True)
Примечания:
- Вызов программы через оболочку обычно не требуется.
Более реалистичный пример будет выглядеть так:
try:
retcode = call("mycmd" + " myarg", shell=True)
if retcode < 0:
print("Child was terminated by signal", -retcode, file=sys.stderr)
else:
print("Child returned", retcode, file=sys.stderr)
except OSError as e:
print("Execution failed:", e, file=sys.stderr)
17.5.6.4. Замена семейства функций 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"})
17.5.6.5. Замена 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
Примечание
Если аргумент 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. Устаревшие функции вызова оболочки
Этот модуль также предоставляет следующие устаревшие функции из модуля 2.x commands. Эти операции подразумевают вызов системной оболочки, и ни одна из описанных выше гарантий относительно безопасности и согласованности обработки исключений не действительна для этих функций.
-
subprocess.getstatusoutput(cmd) -
Возвращает
(exitcode, output)выполнения cmd в оболочке.Выполнить строку cmd в оболочке с
Popen.check_output()и вернуть кортеж из 2 элементов(exitcode, output). Используется кодировка локали; см. примечания к Часто используемые аргументы для получения более подробной информации.Конец строки удаляется из вывода. Код выхода команды можно интерпретировать как код возврата subprocess. Пример:
>>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') >>> subprocess.getstatusoutput('cat /bin/junk') (1, 'cat: /bin/junk: No such file or directory') >>> subprocess.getstatusoutput('/bin/junk') (127, 'sh: /bin/junk: not found') >>> subprocess.getstatusoutput('/bin/kill $$') (-15, '')Доступность: POSIX & Windows
Изменено в версии 3.3.4: Добавлена поддержка Windows.
Теперь функция возвращает (exitcode, output) вместо (status, output), как это было в Python 3.3.3 и ранее. exitcode имеет то же значение, что и
returncode.
-
subprocess.getoutput(cmd) -
Возвращает вывод (stdout и stderr) выполнения cmd в оболочке.
Аналогично
getstatusoutput(), за исключением того, что код завершения игнорируется, а возвращаемое значение — строка, содержащая вывод команды. Пример:>>> subprocess.getoutput('ls /bin/ls') '/bin/ls'Доступность: POSIX & Windows
Изменено в версии 3.3.4: Добавлена поддержка Windows
17.5.8. Примечания
17.5.8.1. Преобразование последовательности аргументов в строку в Windows
В Windows последовательность args преобразуется в строку, которая может быть обработана по следующим правилам (которые соответствуют правилам, используемым MS C runtime):
- Аргументы разделяются пробелами, которые могут быть либо пробелом, либо табуляцией.
- Строка, окружённая двойными кавычками, интерпретируется как один аргумент, независимо от пробелов внутри. В аргументе может быть вложена строка в кавычках.
- Двойная кавычка, предваряемая обратной косой чертой, интерпретируется как буквальная двойная кавычка.
- Обратные косые черты интерпретируются буквально, за исключением случаев, когда они непосредственно предшествуют двойной кавычке.
- Если обратные косые черты непосредственно предшествуют двойной кавычке, каждая пара обратных косых черт интерпретируется как буквальная обратная косая черта. Если количество обратных косых черт нечётное, последняя обратная косая черта экранирует следующую двойную кавычку, как описано в правиле 3.
См. также
-
shlex -
Модуль, предоставляющий функции для разбора и экранирования командных строк.
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.6/library/subprocess.html