Содержание страницы
17.5. subprocess – Управление подпроцессами¶subprocess – Subprocess management
Модуль subprocess позволяет порождать новые процессы, подключаться к их каналам ввода/вывода/ошибок и получать коды возврата. Этот модуль призван заменить несколько более старых модулей и функций:
os.system
os.spawn*
Информация о том, как модуль subprocess может использоваться для замены этих модулей и функций, приведена в следующих разделах.
См. также
PEP 324 – PEP, предлагающий модуль подпроцесса
17.5.1. Использование модуля subprocess¶Using the subprocess Module
Рекомендуемый способ запуска подпроцессов – использовать следующие удобные функции во всех случаях, где они применимы. Для более сложных случаев можно напрямую использовать низкоуровневый интерфейс Popen.
- subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)¶
Выполняет команду, описанную аргументом args. Ожидает завершения команды, затем возвращает атрибут returncode.
Аргументы, перечисленные выше, являются лишь наиболее распространёнными; они описаны ниже в разделе Часто используемые аргументы (отсюда использование нотации только ключевых слов в сокращённой сигнатуре). Полная сигнатура функции в значительной степени совпадает с сигнатурой конструктора Popen – эта функция передаёт все указанные аргументы, кроме timeout, напрямую этому интерфейсу.
Аргумент timeout передаётся в Popen.wait(). Если время ожидания истекает, дочерний процесс будет убит, после чего ожидание повторяется. Исключение TimeoutExpired будет возбуждено повторно после завершения дочернего процесса.
Примеры:
>>> subprocess.call(["ls", "-l"]) 0 >>> subprocess.call("exit 1", shell=True) 1
Предупреждение
Вызов системной оболочки с shell=True может быть опасен для безопасности, если используется вместе с недоверенными входными данными. Подробнее см. предупреждение в разделе Часто используемые аргументы.
Примечание
Не используйте stdout=PIPE или stderr=PIPE с этой функцией. Поскольку каналы не читаются текущим процессом, дочерний процесс может заблокироваться, если он генерирует достаточно выходных данных для заполнения буфера канала ОС.
Изменено в версии 3.3: добавлен timeout.
- subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)¶
Выполняет команду с аргументами. Ожидает завершения команды. Если код возврата равен нулю, возвращает управление, иначе возбуждает CalledProcessError. Объект CalledProcessError будет содержать код возврата в атрибуте returncode.
Аргументы, перечисленные выше, являются лишь наиболее распространёнными; они описаны ниже в разделе Часто используемые аргументы (отсюда использование нотации только ключевых слов в сокращённой сигнатуре). Полная сигнатура функции в значительной степени совпадает с сигнатурой конструктора Popen – эта функция передаёт все указанные аргументы, кроме timeout, напрямую этому интерфейсу.
Аргумент timeout передаётся в Popen.wait(). Если время ожидания истекает, дочерний процесс будет убит, после чего ожидание повторяется. Исключение TimeoutExpired будет возбуждено повторно после завершения дочернего процесса.
Примеры:
>>> subprocess.check_call(["ls", "-l"]) 0 >>> subprocess.check_call("exit 1", shell=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
Предупреждение
Вызов системной оболочки с shell=True может быть опасен для безопасности, если используется вместе с недоверенными входными данными. Подробнее см. предупреждение в разделе Часто используемые аргументы.
Примечание
Не используйте 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.
Аргументы, показанные выше, – это лишь самые распространённые, описанные ниже в разделе Часто используемые аргументы (отсюда использование нотации только ключевых слов в сокращённой сигнатуре). Полная сигнатура функции в значительной мере совпадает с сигнатурой конструктора Popen – эта функция передаёт все переданные аргументы, кроме timeout, непосредственно через этот интерфейс. Кроме того, stdout не допускается в качестве аргумента, так как он используется внутри для сбора вывода от подпроцесса.
Аргумент timeout передаётся в Popen.wait(). Если время ожидания истекает, дочерний процесс будет убит, после чего ожидание повторяется. Исключение TimeoutExpired будет возбуждено повторно после завершения дочернего процесса.
Примеры:
>>> subprocess.check_output(["echo", "Hello World!"]) b'Hello World!\n' >>> subprocess.check_output(["echo", "Hello World!"], universal_newlines=True) 'Hello World!\n' >>> subprocess.check_output("exit 1", shell=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
По умолчанию эта функция возвращает данные в виде закодированных байтов. Фактическая кодировка выходных данных может зависеть от вызываемой команды, поэтому декодирование в текст часто приходится выполнять на уровне приложения.
Это поведение можно переопределить, установив 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.
Предупреждение
Вызов системной оболочки с shell=True может быть опасен для безопасности, если используется вместе с недоверенными входными данными. Подробнее см. предупреждение в разделе Часто используемые аргументы.
Примечание
Не используйте stderr=PIPE с этой функцией. Поскольку канал не читается текущим процессом, дочерний процесс может заблокироваться, если он генерирует достаточно выходных данных для заполнения буфера канала ОС.
Изменено в версии 3.3: добавлен timeout.
- subprocess.DEVNULL¶
Специальное значение, которое может использоваться в качестве аргумента stdin, stdout или stderr для Popen и указывает, что будет использоваться специальный файл os.devnull.
Новое в версии 3.3.
- subprocess.PIPE¶
Специальное значение, которое может использоваться в качестве аргумента stdin, stdout или stderr для Popen и указывает, что должен быть открыт канал к стандартному потоку.
- subprocess.STDOUT¶
Специальное значение, которое может использоваться в качестве аргумента stderr для Popen и указывает, что стандартный поток ошибок должен направляться в тот же дескриптор, что и стандартный вывод.
- exception subprocess.SubprocessError¶
Базовый класс для всех остальных исключений из этого модуля.
Новое в версии 3.3.
- exception subprocess.TimeoutExpired¶
Подкласс SubprocessError, возникающий при истечении тайм-аута в ожидании дочернего процесса.
- cmd¶
Команда, которая использовалась для запуска дочернего процесса.
- timeout¶
Тайм-аут в секундах.
- output¶
Вывод дочернего процесса, если это исключение вызвано check_output(). В противном случае – None.
Новое в версии 3.3.
- exception subprocess.CalledProcessError¶
Подкласс SubprocessError, возникающий, когда процесс, запущенный check_call() или check_output(), возвращает ненулевой код возврата.
- returncode¶
Код возврата дочернего процесса.
- cmd¶
Команда, которая использовалась для запуска дочернего процесса.
- output¶
Вывод дочернего процесса, если это исключение вызвано check_output(). В противном случае – None.
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, эти файловые объекты открываются как текстовые потоки в режиме universal newlines с использованием кодировки, возвращаемой 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 настоятельно не рекомендуется в случаях, когда командная строка формируется из внешних данных:
>>> from subprocess import call >>> filename = input("What file would you like to display?\n") What file would you like to display? non_existent; rm -rf / # >>> call("cat " + filename, shell=True) # Ой-ой. Это плохо кончится...shell=False отключает все функции на основе оболочки, но не подвержен этой уязвимости; обратитесь к примечанию в документации конструктора Popen за полезными советами по настройке shell=False.
При использовании shell=True, shlex.quote() может использоваться для правильного экранирования пробелов и метасимволов оболочки в строках, которые будут использоваться для построения команд оболочки.
Эти параметры, как и все остальные, более подробно описаны в документации конструктора 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=())¶
Запускает дочернюю программу в новом процессе. На Unix класс использует поведение, подобное os.execvp(), для выполнения дочерней программы. На Windows класс использует функцию Windows CreateProcess(). Аргументы Popen следующие.
args должен быть последовательностью аргументов программы или отдельной строкой. По умолчанию, если args является последовательностью, исполняемая программа – это первый элемент в args. Если args – строка, интерпретация зависит от платформы и описана ниже. Дополнительные отличия от поведения по умолчанию см. в аргументах shell и executable. Если не указано иное, рекомендуется передавать args как последовательность.
В Unix, если 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 в виде строки, а не последовательности.
В Unix с 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 означает построчную буферизацию, любое другое положительное значение означает использование буфера приблизительно этого размера. Отрицательное значение 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, как имя команды, которое затем может отличаться от фактически выполняемой программы. В Unix имя args становится отображаемым именем для исполняемого файла в таких утилитах, как ps. Если shell=True, в Unix аргумент executable задаёт заменяющую оболочку для оболочки по умолчанию /bin/sh.
stdin, stdout и stderr задают файловые дескрипторы стандартного ввода, стандартного вывода и стандартного вывода ошибок выполняемой программы соответственно. Допустимые значения: PIPE, DEVNULL, существующий файловый дескриптор (положительное целое число), существующий файловый объект и None. PIPE означает, что должен быть создан новый канал к дочернему процессу. DEVNULL означает, что будет использоваться специальный файл os.devnull. При настройках по умолчанию None перенаправления не происходит; файловые дескрипторы дочернего процесса наследуются от родительского. Кроме того, stderr может быть STDOUT, что означает, что данные stderr из приложений должны захватываться в тот же файловый дескриптор, что и stdout.
Если preexec_fn установлен в вызываемый объект, этот объект будет вызван в дочернем процессе непосредственно перед выполнением дочернего процесса. (только Unix)
Предупреждение
Параметр preexec_fn небезопасно использовать при наличии потоков в приложении. Дочерний процесс может зависнуть до вызова exec. Если его всё же нужно использовать, пусть он будет тривиальным! Сведите к минимуму количество вызываемых библиотек.
Примечание
Если нужно изменить окружение для дочернего процесса, используйте параметр env вместо изменения в preexec_fn. Параметр start_new_session может заменить ранее распространённое использование preexec_fn для вызова os.setsid() в дочернем процессе.
Если close_fds имеет значение true, все файловые дескрипторы, кроме 0, 1 и 2, будут закрыты перед выполнением дочернего процесса. (Только Unix). Значение по умолчанию зависит от платформы: на Unix всегда 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. (Только Unix)
Новое в версии 3.2: Добавлен параметр pass_fds.
Если cwd не равен None, функция меняет рабочий каталог на cwd перед выполнением дочернего процесса. В частности, функция ищет executable (или первый элемент в args) относительно cwd, если путь к исполняемому файлу является относительным.
Если restore_signals имеет значение true (по умолчанию), все сигналы, которые Python установил в SIG_IGN, восстанавливаются до SIG_DFL в дочернем процессе перед exec. В настоящее время это включает сигналы SIGPIPE, SIGXFZ и SIGXFSZ. (Только Unix)
Изменено в версии 3.2: Добавлен restore_signals.
Если start_new_session имеет значение true, системный вызов setsid() будет выполнен в дочернем процессе перед запуском подпроцесса. (Только Unix)
Изменено в версии 3.2: добавлен start_new_session.
Если env не равен None, он должен быть отображением, определяющим переменные окружения для нового процесса; они используются вместо поведения по умолчанию, заключающегося в наследовании окружения текущего процесса.
Примечание
Если задан, то env должен предоставлять все переменные, необходимые для выполнения программы. В Windows, для запуска side-by-side assembly, указанный 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, если вызванный процесс вернёт ненулевой код возврата.
Все функции и методы, принимающие параметр timeout, такие как call() и Popen.communicate(), возбудят TimeoutExpired, если время ожидания истечёт до выхода процесса.
Все исключения, определённые в этом модуле, наследуются от SubprocessError.
Новое в версии 3.3: Был добавлен базовый класс SubprocessError.
17.5.1.4. Безопасность¶Security
В отличие от некоторых других функций popen, данная реализация никогда не вызывает системную оболочку неявно. Это означает, что все символы, включая метасимволы оболочки, можно безопасно передавать дочерним процессам. Очевидно, если оболочка вызывается явно, то приложение отвечает за то, чтобы все пробелы и метасимволы были правильно экранированы.
17.5.2. Объекты Popen¶Popen Objects
Экземпляры класса Popen имеют следующие методы:
- Popen.poll()¶
Проверяет, завершился ли дочерний процесс. Устанавливает и возвращает атрибут returncode.
- Popen.wait(timeout=None)¶
Ожидает завершения дочернего процесса. Устанавливает и возвращает атрибут returncode.
Если процесс не завершается по истечении timeout секунд, возбуждается исключение TimeoutExpired. Это исключение можно безопасно перехватить и повторить ожидание.
Предупреждение
Это приведёт к взаимоблокировке при использовании stdout=PIPE и/или stderr=PIPE, если дочерний процесс генерирует достаточно выходных данных для канала, так что он блокируется в ожидании, пока буфер канала ОС сможет принять больше данных. Используйте communicate(), чтобы избежать этого.
Изменено в версии 3.3: добавлен timeout.
- Popen.communicate(input=None, timeout=None)¶
Взаимодействует с процессом: отправляет данные в stdin. Читает данные из stdout и stderr до достижения конца файла. Ожидает завершения процесса. Необязательный аргумент input должен содержать данные для отправки дочернему процессу, или None, если данные отправлять не нужно. Тип input должен быть bytes или, если universal_newlines был True, строкой.
communicate() возвращает кортеж (stdoutdata, stderrdata).
Обратите внимание: для отправки данных в stdin процесса объект Popen должен быть создан с stdin=PIPE. Аналогично, чтобы получить в результирующем кортеже что-либо, кроме None, нужно также указать stdout=PIPE и/или stderr=PIPE.
Если процесс не завершится через timeout секунд, будет возбуждено исключение TimeoutExpired. Перехват этого исключения и повторный вызов communication не приведёт к потере вывода.
Дочерний процесс не уничтожается по истечении тайм-аута, поэтому для корректной очистки хорошо написанное приложение должно уничтожить дочерний процесс и завершить обмен данными:
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().
Также доступны следующие атрибуты:
Предупреждение
Используйте communicate() вместо .stdin.write, .stdout.read или .stderr.read, чтобы избежать взаимоблокировок из-за переполнения любого из буферов других каналов ОС, что блокирует дочерний процесс.
- 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.
- Popen.pid¶
PID дочернего процесса.
Обратите внимание: если установить аргумент shell в значение True, то это будет идентификатор процесса запущенной оболочки.
- Popen.returncode¶
Код возврата дочернего процесса, устанавливаемый методами poll() и wait() (а косвенно и communicate()). Значение None указывает, что процесс ещё не завершён.
Отрицательное значение -N означает, что дочерний процесс был завершён сигналом N (только в Unix).
17.5.3. Вспомогательные средства 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¶
If dwFlags specifies STARTF_USESTDHANDLES, this attribute is the standard error handle for the process. Otherwise, this attribute is ignored and the default for standard error is the console window’s buffer.
- wShowWindow¶
Если в dwFlags указан флаг STARTF_USESHOWWINDOW, то этот атрибут может принимать любое из значений, допустимых для параметра nCmdShow функции ShowWindow, за исключением SW_SHOWDEFAULT. В противном случае данный атрибут игнорируется.
Для этого атрибута предусмотрено значение SW_HIDE. Оно используется, когда Popen вызывается с параметром shell=True.
17.5.3.1. Константы¶Constants
Модуль подпроцесс предоставляет следующие константы.
- 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¶
Новый процесс получает новую консоль вместо наследования консоли родителя (по умолчанию).
Этот флаг всегда устанавливается, когда Popen создаётся с shell=True.
- subprocess.CREATE_NEW_PROCESS_GROUP¶
Параметр creationflags функции Popen, указывающий, что будет создана новая группа процессов. Этот флаг необходим для использования os.kill() для подпроцесса.
Этот флаг игнорируется, если указан CREATE_NEW_CONSOLE.
17.5.4. Замена старых функций модулем подпроцесс¶Replacing Older Functions with the subprocess Module
В этом разделе «a становится b» означает, что b можно использовать как замену для a.
Примечание
Все функции «a» в этом разделе при ненахождении исполняемой программы выдают ошибку (более или менее) молча; замены «b» вместо этого возбуждают исключение OSError.
Кроме того, замены с использованием check_output() завершатся ошибкой с исключением CalledProcessError, если запрошенная операция вернёт ненулевой код возврата. Вывод по-прежнему доступен как атрибут output возбуждённого исключения.
В следующих примерах предполагается, что соответствующие функции уже импортированы из модуля подпроцесс.
17.5.4.1. Замена обратной кавычки оболочки /bin/sh¶Replacing /bin/sh shell backquote
output=`mycmd myarg`
# becomes
output = check_output(["mycmd", "myarg"])
17.5.4.2. Замена конвейера оболочки¶Replacing shell pipeline
output=`dmesg | grep hda`
# becomes
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`
# becomes
output=check_output("dmesg | grep hda", shell=True)
17.5.4.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.4.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.4.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, 'w', stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
print("There were some errors")
17.5.4.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 по умолчанию закрывает все файловые дескрипторы, но для гарантии такого поведения на всех платформах или в старых версиях Python необходимо указать close_fds=True вместе с Popen.
17.5.5. Устаревшие функции вызова оболочки¶Legacy Shell Invocation Functions
Этот модуль также предоставляет следующие устаревшие функции из модуля commands версии 2.x. Эти операции неявно вызывают системную оболочку, и ни одно из описанных выше гарантий безопасности и согласованности обработки исключений для этих функций не действует.
- subprocess.getstatusoutput(cmd)¶
Возвращает (status, output) выполнения cmd в оболочке.
Выполняет строку cmd в оболочке с помощью Popen и возвращает кортеж из двух элементов (status, output) через Popen.communicate(). Используется режим универсальных новых строк; подробнее см. в примечаниях к Часто используемые аргументы.
Завершающий символ новой строки удаляется из вывода. Код возврата команды можно интерпретировать по правилам для 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')
Доступность: Unix и Windows
Изменено в версии 3.3.4: Добавлена поддержка Windows
- subprocess.getoutput(cmd)¶
Возвращает вывод (stdout и stderr) выполнения cmd в оболочке.
Аналогично getstatusoutput(), за исключением того, что код возврата игнорируется, а возвращаемое значение – строка, содержащая вывод команды. Пример:
>>> subprocess.getoutput('ls /bin/ls') '/bin/ls'
Доступность: Unix и Windows
Изменено в версии 3.3.4: Добавлена поддержка Windows
17.5.6. Примечания¶Notes
17.5.6.1. Преобразование последовательности аргументов в строку в Windows¶Converting an argument sequence to a string on Windows
В Windows последовательность args преобразуется в строку, которая может быть разобрана с помощью следующих правил (которые соответствуют правилам, используемым в MS C runtime):
- Аргументы разделяются пробельными символами, то есть пробелом или табуляцией.
- Строка, заключённая в двойные кавычки, интерпретируется как один аргумент, независимо от пробельных символов внутри неё. Строка в кавычках может быть встроена в аргумент.
- Двойная кавычка, перед которой стоит обратная косая черта, интерпретируется как литеральная двойная кавычка.
- Обратные косые черты интерпретируются буквально, если только они не стоят непосредственно перед двойной кавычкой.
- Если обратные косые черты стоят непосредственно перед двойной кавычкой, каждая пара обратных косых черт интерпретируется как литеральная обратная косая черта. Если количество обратных косых черт нечётное, последняя обратная косая черта экранирует следующую за ней двойную кавычку, как описано в правиле 3.
См. также
- shlex
- Модуль, предоставляющий функцию для разбора и экранирования командных строк.