17.5. subprocess – Управление подпроцессами
Исходный код: Lib/subprocess.py
Модуль subprocess позволяет порождать новые процессы, подключаться к их каналам ввода/вывода/ошибок и получать коды возврата. Этот модуль призван заменить несколько более старых модулей и функций:
os.system
os.spawn*
Информацию о том, как использовать модуль subprocess для замены этих модулей и функций, можно найти в следующих разделах.
Смотрите также
PEP 324 – PEP, предлагающий модуль подпроцессов
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()и, таким образом, в stdin подпроцесса. Если он используется, то должен быть последовательностью байтов или строкой, если указаны encoding или errors, либо universal_newlines имеет значение true. При использовании внутренний объектPopenавтоматически создаётся сstdin=PIPE, и аргумент stdin также не может использоваться.Если check истинно, и процесс завершается с ненулевым кодом возврата, будет вызвано исключение
CalledProcessError. Атрибуты этого исключения содержат аргументы, код возврата, а также stdout и stderr, если они были захвачены.Если указаны encoding или errors, или universal_newlines имеет значение true, файловые объекты для stdin, stdout и stderr открываются в текстовом режиме с использованием указанных encoding и errors или значения по умолчанию
io.TextIOWrapper. В противном случае файловые объекты открываются в двоичном режиме.Если env не равно
None, оно должно быть отображением, определяющим переменные окружения для нового процесса; эти переменные используются вместо поведения по умолчанию – наследования окружения текущего процесса. Оно передаётся напрямую вPopen.Примеры:
python>>> 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.
Изменено в версии 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и указывает, что должен быть открыт канал (pipe) к стандартному потоку. Наиболее полезно сPopen.communicate().
-
subprocess.STDOUT¶ Специальное значение, которое может использоваться как аргумент stderr для
Popenи указывает, что стандартный поток ошибок должен направляться в тот же дескриптор (handle), что и стандартный вывод.
-
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. Часто используемые аргументы
Чтобы поддерживать широкий круг вариантов использования, конструктор 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, особенно в сложных случаях:python>>> 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делает эквивалент:pythonPopen(['/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). Значение по умолчанию зависит от платформы: на POSIX всегда true. На 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 для запуска сторонней сборки (side-by-side assembly) указанный 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: при выходе стандартные файловые дескрипторы закрываются, и ожидается завершение процесса.pythonwith 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()при работе с каналами, чтобы избежать этого.Примечание
Функция реализована с помощью цикла ожидания (неблокирующий вызов и короткие паузы). Используйте модуль
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. Перехват этого исключения и повторный обмен данными не приведет к потере вывода.Дочерний процесс не убивается по истечении тайм-аута, поэтому для корректной очистки хорошо написанное приложение должно убить дочерний процесс и завершить communication:
pythonproc = 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. Вспомогательные функции Popen для Windows
Класс STARTUPINFO и следующие константы доступны только на Windows.
-
class
subprocess.STARTUPINFO¶ Частичная поддержка структуры Windows STARTUPINFO используется для создания
Popen.-
dwFlags¶ Битовое поле, определяющее, используются ли определённые атрибуты
STARTUPINFOпри создании окна процессом.pythonsi = 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¶ Параметр
Popencreationflags, указывающий, что будет создана новая группа процессов. Этот флаг необходим для использованияos.kill()в подпроцессе.Этот флаг игнорируется, если указан
CREATE_NEW_CONSOLE.
17.5.5. Устаревший высокоуровневый API
До Python 3.5 эти три функции составляли высокоуровневый API для
подпроцессов. Теперь во многих случаях можно использовать run(), но много существующего кода
вызывает эти функции.
-
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None)¶ Выполняет команду, описанную в args. Ожидает завершения команды, затем возвращает атрибут
returncode.Это эквивалентно:
pythonrun(...).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.Это эквивалентно:
pythonrun(..., 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.Это эквивалентно:
pythonrun(..., check=True, stdout=PIPE).stdoutПоказанные выше аргументы – лишь наиболее распространённые. Полная сигнатура функции в основном совпадает с сигнатурой
run()– большинство аргументов передаются напрямую в этот интерфейс. Однако явная передачаinput=Noneдля наследования дескриптора стандартного ввода родительского процесса не поддерживается.По умолчанию эта функция возвращает данные в виде закодированных байтов. Фактическая кодировка выходных данных может зависеть от вызванной команды, поэтому декодирование в текст часто нужно выполнять на уровне приложения.
Это поведение можно переопределить, установив universal_newlines в
True, как описано выше в разделе Часто используемые аргументы.Чтобы также захватывать стандартный поток ошибок в результате, используйте
stderr=subprocess.STDOUT:python>>> 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() # Разрешить 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()
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
Пример 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"])
Пример Vector:
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. Устаревшие функции вызова оболочки
Этот модуль также предоставляет следующие устаревшие функции из модуля commands версии 2.x. Эти операции неявно вызывают системную оболочку, и ни одна из гарантий безопасности и единообразия обработки исключений, описанных выше, не действует для этих функций.
-
subprocess.getstatusoutput(cmd)¶ Возвращает
(exitcode, output)выполнения cmd в оболочке.Выполняет строку cmd в оболочке с
Popen.check_output()и возвращает кортеж из двух элементов(exitcode, output). Используется локальная кодировка; см. примечания к разделу Часто используемые аргументы для получения дополнительных сведений.Замыкающий символ новой строки удаляется из вывода. Код выхода команды можно интерпретировать как код возврата подпроцесса. Пример:
python>>> 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(), за исключением того, что код выхода игнорируется, а возвращаемое значение – строка, содержащая вывод команды. Пример:python>>> 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):
Аргументы разделяются пробельными символами, то есть пробелом или табуляцией.
Строка, заключенная в двойные кавычки, интерпретируется как один аргумент, независимо от содержащихся в ней пробельных символов. Строка в кавычках может быть вложена в аргумент.
Двойная кавычка, перед которой стоит обратная косая черта, интерпретируется как литеральная двойная кавычка.
Обратные косые черты интерпретируются буквально, если только они не стоят непосредственно перед двойной кавычкой.
Если обратные косые черты стоят непосредственно перед двойной кавычкой, каждая пара обратных косых черт интерпретируется как одна литеральная обратная косая черта. Если количество обратных косых черт нечетное, последняя обратная косая черта экранирует следующую двойную кавычку, как описано в правиле 3.
Смотрите также
shlexМодуль, предоставляющий функцию для разбора и экранирования командных строк.