subprocess — Управление подпроцессами

Исходный код: Lib/subprocess.py


Модуль subprocess позволяет создавать новые процессы, подключаться к их пайпы ввода/вывода/ошибки и получать их возвращает коды. Этот модуль предназначен для замены нескольких старых модулей и функций:

os.system
os.spawn*

Информацию о том, как можно используемый модуль subprocess для замены этих модулей и функций, можно найти в следующих разделах.

См.также

PEP 324 – PEP предлагает модуль subprocess

Использование модуля subprocess

Рекомендуемый подход к вызову подпроцессов заключается в использовании функции run() для всех вариантов использования, которые она может обрабатывать. Для более продвинутых сценариев использования базовый интерфейс Popen можно используемый непосредственно.

Функция run() была добавлена в Python 3.5; если необходимо сохранить совместимость со старыми версиями, см. раздел Старый высокоуровневый API.

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None, **other_popen_kwargs)

Выполнить команду, описанную args. Дождаться завершения команды, а затем возвращает CompletedProcess сущность.

Приведенные выше аргументы являются лишь наиболее распространенными аргументами, описанными ниже в Часто используемые аргументы (следовательно, использование ключевой-only обозначения в сокращенном сигнатура). Полная сигнатура функции в значительной степени аналогична функции конструктора Popen - большая часть аргументов этой функции передается через этот интерфейс. (timeout, input, check и capture_output - нет.)

Если capture_output верно, будут зафиксированы stdout и stderr. При используемый внутренний объект Popen автоматически создается с помощью stdout=PIPE и stderr=PIPE. Аргументы stdout и stderr не могут быть предоставлены одновременно с аргументами capture_output. Если вы хотите захватить и объединить оба потока в один, используйте stdout=PIPE и stderr=STDOUT вместо capture_output.

Аргумент timeout передается Popen.communicate(). Если тайм-аут истекает, дочерний процесс будет остановлен и выжидать. Исключение TimeoutExpired будет повторно создано после завершения дочернего процесса.

Аргумент input передается в Popen.communicate() и, таким образом, в stdin подпроцессы. Если используемый, то это должна быть последовательность байтов или строкой, если encoding или errors указан или text имеет значение true. При используемый внутренний объект Popen автоматически создается с помощью stdin=PIPE, и аргумент stdin также не может быть используемый.

Если check имеет значение true, и процесс завершается с ненулевым код выхода, создается CalledProcessError исключение. Атрибуты этого исключения содержат аргументы, код выхода, stdout и stderr, если они были захвачены.

Если указаны encoding или errors или text имеет значение true, файловые объекты для stdin, stdout и stderr открываются в текстовом режиме с использованием указанных encoding и errors или io.TextIOWrapper по умолчанию. Аргумент universal_newlines эквивалентен text и обеспечивает обратную совместимость. По умолчанию объекты файла открываются в двоичном режиме.

Если env не None, это должно быть сопоставление, определяющее переменные среды для нового процесса; это используемый вместо поведения по умолчанию наследования среды текущего процесса. Он передается непосредственно Popen.

Примеры:

>>> 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"], capture_output=True)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n', stderr=b'')

Добавлено в версии 3.5.

Изменено в версии 3.6: Добавлены параметры encoding и errors

Изменено в версии 3.7: Добавлен параметр text, как более понятный алиас universal_newlines. Добавлен параметр capture_output.

class subprocess.CompletedProcess

Возвращает значение из run(), представляющего завершившийся процесс.

args

Аргументы используемый для запуска процесса. Это может быть список или строка.

returncode

Состояние выхода дочернего процесса. Как правило, состояние выхода 0 указывает на успешное выполнение.

Отрицательное значение -N указывает на то, что дочерний объект был завершен сигналом N (только POSIX).

stdout

Отснятый stdout из дочернего процесса. Последовательность байтов или строка, если run() был вызван с кодировка, ошибками или текстом = True. None, если stdout не был захвачен.

Если процесс выполнялся с stderr=subprocess.STDOUT, stdout и stderr будут объединены в этом атрибут, и stderr будут None.

stderr

Захват stderr из дочернего процесса. Последовательность байтов или строка, если run() был вызван с кодировка, ошибками или текстом = True. None, если stderr не был захвачен.

check_returncode()

Если returncode ненулевое, поднимите CalledProcessError.

Добавлено в версии 3.5.

subprocess.DEVNULL

Специальный значение, которое может быть используемо как stdin, stdout или аргументом stderr Popen и указывает, что специальный файл os.devnull будет используемый.

Добавлено в версии 3.3.

subprocess.PIPE

Специальный значение, которое может быть используемо в качестве аргумента stdin, stdout или stderr для Popen и указывает на необходимость открытия пайп стандартного потока. Наиболее полезно с Popen.communicate().

subprocess.STDOUT

Специальная значение, которое может быть используемо в качестве аргумента stderr для Popen и указывает, что стандартная ошибка должна входить в тот же дескриптор, что и стандартный вывод.

exception subprocess.SubprocessError

Базовый класс для всех других исключений из этого модуля.

Добавлено в версии 3.3.

exception subprocess.TimeoutExpired

Подкласс SubprocessError, возникающий при истечении времени ожидания дочернего процесса.

cmd

Команда, используемый для создания дочернего процесса.

timeout

Тайм-аут в секундах.

output

Вывод дочернего процесса, если он был захвачен run() или check_output(). Иначе, None.

stdout

Псевдоним для вывода, для симметрии с 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

Псевдоним для вывода, для симметрии с stderr.

stderr

Вывод Stderr дочернего процесса, если он был захвачен run(). Иначе, None.

Изменено в версии 3.5: stdout и stderr атрибуты добавлены

Часто используемые аргументы

Для поддержки широкого спектра вариантов использования конструктор Popen (и функции удобства) принимает большое количество необязательных аргументов. Для большинства типичных вариантов использования многие из этих аргументов можно безопасно оставить на значения по умолчанию. Наиболее часто необходимыми аргументами являются:

args требуется для всех вызовов и должен быть строкой или последовательностью программных аргументов. Предоставление последовательности аргументов, как правило, является предпочтительным, так как оно позволяет модулю заботиться о любых необходимых отклонениях и цитировании аргументов (например, разрешить пробелы в именах файлов). При передаче одного строка либо shell должен быть True (см. ниже), либо строка должен просто назвать выполняемую программу без указания каких-либо аргументов.

stdin, stdout и stderr соответственно определяют стандартный ввод, стандартный вывод и стандартный файл ошибок исполняемой программы. Допустимыми значения являются PIPE, DEVNULL, существующий дескриптор файла (положительное целое число), существующий объект файла и None. PIPE указывает на необходимость создания нового пайп для нижестоящего элемента. DEVNULL указывает, что специальный os.devnull файла будет используемый. При заданных по умолчанию параметрах None перенаправление не выполняется; дескрипторы файлов нижестоящего элемента наследуются от родительского элемента. Кроме того, stderr может быть STDOUT, что указывает на то, что данные stderr из дочернего процесса должны быть записаны в тот же дескриптор файла, что и для stdout.

Если указаны encoding или errors или text (также называемый universal_newlines), то объекты файла stdin, stdout и stderr будут открыты в текстовом режиме с использованием encoding и errors, указанных в вызове, или значений по умолчанию для io.TextIOWrapper.

Для stdin символы окончания строки, '\n' на входе, будут преобразованы в os.linesep разделителя строк по умолчанию. Для stdout и stderr все окончания строк в выходных данных будут преобразованы в '\n'. Дополнительные сведения см. в документации класса io.TextIOWrapper при None аргумента newline конструктору.

Если текстовый режим не используемый, stdin, stdout и stderr будут открыты как двоичные потоки. Преобразование кодировка или окончания строки не выполняется.

Добавлено в версии 3.6: Добавлены параметры encoding и errors.

Добавлено в версии 3.7: Добавлен параметр text в качестве алиас для universal_newlines.

Примечание

Новые строки атрибут файловых объектов Popen.stdin, Popen.stdout и Popen.stderr не обновляются методом Popen.communicate().

Если shell True, указанная команда будет выполнена через оболочку. Это может быть полезно, если вы используете Python в основном для расширенного потока управления, который он предлагает для большинства системных оболочек, и по-прежнему хотите получить удобный доступ к другим функциям оболочки, таким как пайпы оболочки, подстановочные символы имен файлов, расширение переменных среды и расширение ~ в домашнюю папку пользователя. Однако следует отметить, что сама Python предлагает реализации многих оболочечных функций (в частности, glob, fnmatch, os.walk(), os.path.expandvars(), os.path.expanduser() и shutil).

Изменено в версии 3.3: Когда universal_newlines равно True, класс использует кодировка locale.getpreferredencoding(False) вместо locale.getpreferredencoding(). Дополнительные сведения об этом изменении см. в классе io.TextIOWrapper.

Примечание

Прочитайте раздел Соображения безопасности перед использованием shell=True.

Эти опции наряду со всеми другими опциями более подробно описаны в документации конструктора Popen.

Конструктор Popen

Создание базового процесса и управление им в этом модуле осуществляется классом Popen. Она предлагает много гибкости, чтобы разработчики могли обрабатывать менее распространенные случаи, не охваченные удобными функциями.

class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None)

Выполнить дочернюю программу в новом процессе. В POSIX класс использует os.execvp()-подобное поведение для выполнения дочерней программы. В Windows класс использует функцию Windows CreateProcess(). Аргументы для Popen следующие.

args должен быть последовательностью программных аргументов или одиночной строкой или путеподобным объектом. По умолчанию выполняемая программа является первым элементом в args, если args является последовательностью. Если args является строка, интерпретация зависит от платформы и описана ниже. Дополнительные отличия от поведения по умолчанию см. в аргументах shell и executable. Если не указано иное, рекомендуется передавать args в виде последовательности.

Примером передачи некоторых аргументов внешней программе в качестве последовательности является:

Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."])

В POSIX, если args является строка, строка интерпретируется как имя или путь исполняемой программы. Однако это можно сделать, только если не передавать аргументы программе.

Примечание

Может быть неочевидным, как разбить команду оболочки на последовательность аргументов, особенно в сложных случаях. shlex.split() может проиллюстрировать, как определить правильную маркировку для args:

>>> import shlex, subprocess
>>> command_line = input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print(args)
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!

Обратите внимание, в частности, что параметры (например, -input) и аргументы (например, eggs.txt), разделенные пробелом в оболочке, находятся в отдельных элементах списка, в то время как аргументы, которые требуют кавычек или обратной косой черты при используемый в оболочке (например, имена файлов, содержащие пробелы, или команда echo, показанная выше), являются элементами одного списка.

В Windows, если args является последовательностью, она будет преобразована в строка способом, описанным в Преобразование последовательности аргументов в строку в Windows. Это происходит потому, что основной CreateProcess() работает на строки.

Изменено в версии 3.6: args параметр принимает путеподобный объект, если shell False, и последовательность, содержащую похожие на путь объекты в POSIX.

Изменено в версии 3.8: args параметр принимает путеподобный объект, если shell False, и последовательность, содержащую байты и похожие на путь объекты в Windows.

Аргумент shell (по умолчанию - False) указывает, следует ли использовать оболочку в качестве исполняемой программы. Если shell True, рекомендуется передавать args как строка, а не как последовательность.

В POSIX с shell=True оболочка по умолчанию имеет значение /bin/sh. Если args является строка, строка задает команду для выполнения через оболочку. Это означает, что строка должен быть отформатирован точно так же, как при вводе в командной строке. К ним относятся, например, кавычки или обратная косая черта между именами файлов и пробелами в них. Если args является последовательностью, первый элемент определяет строка команды, и любые дополнительные элементы будут рассматриваться как дополнительные аргументы для самой оболочки. То есть, Popen делает эквивалент:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

В Windows с shell=True переменная среды COMSPEC задает оболочку по умолчанию. Единственный раз, когда необходимо указать shell=True в Windows, это когда команда, которую требуется выполнить, встроена в оболочку (например, dir или copy). Для запуска пакетного файла или консольного исполняемого файла shell=True не требуется.

Примечание

Прочитайте раздел Соображения безопасности перед использованием shell=True.

bufsize будет предоставлен в качестве соответствующего аргумента функции open() при создании объектов stdin/stdout/stderr пайпа файла:

  • 0 означает небуферизован (чтение и запись являются одним системным вызовом и могут возвращает короткими)
  • 1 означает, что строка буферизирована (может использоваться только, если universal_newlines=True т.е. в текстовом режиме),
  • любые другие положительные значение средства используют буфер приблизительно такого размера,
  • что отрицательный размер буфера (по умолчанию) означает системное значение по умолчанию io. Будет DEFAULT_BUFFER_SIZE используемый.

Изменено в версии 3.3.1: По умолчанию bufsize имеет значение -1, чтобы включить буферизацию по умолчанию для соответствия поведению, ожидаемому большинством код. В версиях до Python 3.2.4 и 3.3.1 он ошибочно по умолчанию стал 0, который был необустановлен и допускал короткие чтения. Это было непреднамеренно и не соответствовало поведению Python 2, как ожидалось большинство код.

Аргумент executable указывает исполняемую программу замены. Это очень редко нужно. При shell=False executable заменяет выполняемую программу, указанную в args. Однако оригинальный args всё же передан программе. Большинство программ рассматривают программу, указанную args, как имя команды, которое затем может отличаться от фактически выполняемой программы. В POSIX имя args становится отображаемым именем исполняемого файла в таких утилитах, как ps. Если shell=True, в POSIX аргумент executable указывает заменяющую оболочку для /bin/sh по умолчанию.

Изменено в версии 3.6: executable параметр принимает путеподобный объект в POSIX.

Изменено в версии 3.8: executable параметр принимает байты и путеподобный объект в Windows.

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() в дочернем элементе.

Изменено в версии 3.8: Параметр preexec_fn больше не поддерживается в субинтерфейсах. Использование параметра в субинтерпретере вызывает RuntimeError. Новое ограничение может затронуть приложения, развернутые в mod_wsgi, uWSGI и других встроенных средах.

Если close_fds имеет значение true, все дескрипторы файлов, кроме 0, 1 и 2, будут закрыты перед выполнением дочернего процесса. В противном случае, если close_fds имеет значение false, дескрипторы файла подчиняются их наследуемому флагу, как описано в разделе Наследование файловых дескрипторов.

В Windows, если close_fds имеет значение true, дочерний процесс не будет наследовать дескрипторы, если они явно не переданы в handle_list элементе STARTUPINFO.lpAttributeList или не будут перенаправлены стандартным дескриптором.

Изменено в версии 3.2: Значение по умолчанию для close_fds было изменено с False на описанное выше.

Изменено в версии 3.7: В Windows значение по умолчанию для close_fds было изменено с False на True при перенаправлении стандартных дескрипторов. Теперь можно установить close_fds на True при перенаправлении стандартных дескрипторов.

pass_fds является необязательной последовательностью дескрипторы файлов, которые должны оставаться открытыми между родителем и потомком. Обеспечение любых pass_fds сил close_fds подлежащих True. (Только POSIX)

Изменено в версии 3.2: Добавлен параметр pass_fds.

Если cwd не None, функция изменяет рабочий каталог на cwd перед выполнением нижестоящего элемента. cwd может быть объектом строка, байтов или путеподобный. В частности, функция ищет executable (или первый элемент в args) относительно cwd, если исполняемый путь является относительным путем.

Изменено в версии 3.6: cwd параметр принимает путеподобный объект в POSIX.

Изменено в версии 3.7: cwd параметр принимает путеподобный объект в Windows.

Изменено в версии 3.8: cwd параметр принимает байтовый объект в Windows.

Если restore_signals имеет значение true (по умолчанию), все сигналы, для которых Python установлено значение SIG_IGN, восстанавливаются для SIG_DFL в дочернем процессе перед выполнением. В настоящее время это включает сигналы SIGPIPE, SIGXFZ и SIGXFSZ. (Только POSIX)

Изменено в версии 3.2: restore_signals было добавлено.

Если start_new_session верно, системный вызов setsid() будет выполнен в дочернем процессе до выполнения подпроцессы. (Только POSIX)

Изменено в версии 3.2: start_new_session было добавлено.

Если env не None, это должно быть сопоставление, определяющее переменные среды для нового процесса; это используемый вместо поведения по умолчанию наследования среды текущего процесса.

Примечание

Если указано, env должны содержать переменные, необходимые для выполнения программы. В Windows для запуска сборка бок о бок указанный env должен содержать допустимое SystemRoot.

Если указаны encoding или errors, или text имеет значение true, объекты файла stdin, stdout и stderr открываются в текстовом режиме с указанными кодировка и errors, как описано выше в разделе Часто используемые аргументы. Аргумент universal_newlines эквивалентен text и обеспечивает обратную совместимость. По умолчанию объекты файла открываются в двоичном режиме.

Добавлено в версии 3.6: Были добавлены encoding и errors.

Добавлено в версии 3.7: text был добавлен в качестве более читаемого алиас для universal_newlines.

Если задано, startupinfo будет STARTUPINFO объект, который передается базовой функции CreateProcess. creationflags, если он задан, может быть одним или несколькими из следующих флагов:

Объекты Popen поддерживаются как менеджеры контекст через with инструкция: при выходе закрываются стандартные файловые дескрипторы, и процесс ожидает.:

with Popen(["ifconfig"], stdout=PIPE) as proc:
    log.write(proc.stdout.read())

Popen и другие функции в этом модуле, которые используют его, создают событие аудита subprocess.Popen с аргументами executable, args, cwd и env. В зависимости от платформы значение для args может быть одним строка или списком строки.

Изменено в версии 3.2: Добавлена поддержка менеджера контекста.

Изменено в версии 3.6: Теперь Popen деструктор выдает предупреждение о ResourceWarning, если дочерний процесс все еще выполняется.

Изменено в версии 3.8: В некоторых случаях Popen может использовать os.posix_spawn() для повышения производительности. В подсистеме Windows для Linux и эмуляции пользователей QEMU конструктор Popen, использующий os.posix_spawn(), больше не создает исключение для ошибок, таких как отсутствие программы, но дочерний процесс завершается с ненулевым returncode.

Исключения

Исключения, возникшие в дочернем процессе до начала выполнения новой программы, будут повторно созданы в родительском процессе.

Наиболее распространенным исключением является OSError. Это происходит, например, при попытке выполнить несуществующий файл. Заявки должны готовиться к OSError исключениям.

Если ValueError вызывается с недопустимыми аргументами, то возникает Popen.

check_call() и check_output() вызовет CalledProcessError, если вызываемый процесс возвращает ненулевой код возвращения.

Все функции и методы, принимающие параметр timeout, такие как call() и Popen.communicate(), будут создавать TimeoutExpired, если время ожидания истекает до завершения процесса.

Исключения, определенные в этом модуле, наследуют от SubprocessError.

Добавлено в версии 3.3: Добавлен базовый класс SubprocessError.

Соображения безопасности

В отличие от некоторых других функций popen, эта реализация никогда не будет неявно вызывать системную оболочку. Это означает, что все символы, включая метасимволы оболочки, могут быть безопасно переданы дочерним процессам. Если оболочка вызывается явным образом через shell=True, приложение обязано обеспечить, чтобы все пробелы и метасимволы были указаны соответствующим образом, чтобы избежать инъекцию оболочки уязвимостей.

При использовании shell=True можно используемый функцию shlex.quote(), чтобы правильно избежать пробелов и метасимволов оболочки в строки, которые будут используемый для создания команд оболочки.

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 было добавлено.

Popen.communicate(input=None, timeout=None)

Взаимодействие с процессом: отправка данных на стандартный ввод. Прочитать данные из stdout и stderr, пока не будет достигнут конец файла. Подождать, пока процесс завершится, и установить атрибут returncode. Необязательный аргумент 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).

Помощники Windows Popen

Класс STARTUPINFO и следующие константы доступны только в Windows.

class subprocess.STARTUPINFO(*, dwFlags=0, hStdInput=None, hStdOutput=None, hStdError=None, wShowWindow=0, lpAttributeList=None)

Частичная поддержка структуры Windows STARTUPINFO используемый для создания Popen. Следующие атрибуты можно задать, передав их в качестве только ключевых аргументов.

Изменено в версии 3.7: Добавлена поддержка аргументов только по ключевым словам.

dwFlags

Битовое поле, определяющее, STARTUPINFO ли определенные атрибуты используемый при создании окна процессом.:

si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
hStdInput

Если dwFlags указывает STARTF_USESTDHANDLES, этот атрибут является стандартным дескриптором ввода для процесса. Если STARTF_USESTDHANDLES не указан, по умолчанию для стандартного ввода используется буфер клавиатуры.

hStdOutput

Если dwFlags указывает STARTF_USESTDHANDLES, этот атрибут является стандартным дескриптором вывода для процесса. В противном случае этот атрибут игнорируется, и по умолчанию стандартным выводом является буфер окна консоли.

hStdError

Если dwFlags указывает STARTF_USESTDHANDLES, этот атрибут является стандартным дескриптором ошибки для процесса. В противном случае эта атрибут игнорируется, и по умолчанию стандартной ошибкой является буфер окна консоли.

wShowWindow

Если dwFlags указывает STARTF_USESHOWWINDOW, этот атрибут может быть любым из значения, которые могут быть указаны в параметре nCmdShow для функции ShowWindow, за исключением SW_SHOWDEFAULT. В противном случае этот атрибут игнорируется.

Для этого SW_HIDE предусмотрена атрибут. Это используемый, когда Popen вызывается с shell=True.

lpAttributeList

Словарь дополнительных атрибуты для создания процесса, приведенный в STARTUPINFOEX, см. UpdateProcThreadAttribute.

Поддержанный атрибуты:

handle_list

Последовательность дескрипторов, которые будут унаследованы. close_fds должен иметь значение true, если он не пуст.

Дескрипторы должны быть временно унаследованы os.set_handle_inheritable() при передаче конструктору Popen, в противном случае OSError будут вызваны ошибкой Windows ERROR_INVALID_PARAMETER (87).

Предупреждение

В многопоточном процессе следует избегать утечки дескрипторов, которые помечены как наследуемые, при объединении этой функции с параллельными вызовами других функций создания процессов, которые наследуют все дескрипторы, такие как os.system(). Это также относится к стандартному перенаправлению дескрипторов, которое временно создает наследуемые дескрипторы.

Добавлено в версии 3.7.

Windows константы

Модуль subprocess предоставляет следующие константы.

subprocess.STD_INPUT_HANDLE

Стандартное устройство ввода. Первоначально это входной буфер консоли, CONIN$.

subprocess.STD_OUTPUT_HANDLE

Стандартное устройство вывода. Первоначально это активный буфер экрана консоли, CONOUT$.

subprocess.STD_ERROR_HANDLE

Стандартное устройство ошибки. Первоначально это активный буфер экрана консоли, CONOUT$.

subprocess.SW_HIDE

Скрывает окно. Будет активировано другое окно.

subprocess.STARTF_USESTDHANDLES

Определяет, что STARTUPINFO.hStdInput, STARTUPINFO.hStdOutput и STARTUPINFO.hStdError атрибуты содержат дополнительную информацию.

subprocess.STARTF_USESHOWWINDOW

Указывает, что STARTUPINFO.wShowWindow атрибут содержит дополнительную информацию.

subprocess.CREATE_NEW_CONSOLE

Новый процесс имеет новую консоль вместо наследования родительской консоли (по умолчанию).

subprocess.CREATE_NEW_PROCESS_GROUP

Параметр Popen creationflags, указывающий, что будет создана новая группа процессов. Этот флаг необходим для использования os.kill() на подпроцессы.

Этот флаг игнорируется, если указан CREATE_NEW_CONSOLE.

subprocess.ABOVE_NORMAL_PRIORITY_CLASS

Параметр Popen creationflags, указывающий, что новый процесс будет иметь приоритет выше среднего.

Добавлено в версии 3.7.

subprocess.BELOW_NORMAL_PRIORITY_CLASS

Параметр Popen creationflags, указывающий, что новый процесс будет иметь приоритет ниже среднего.

Добавлено в версии 3.7.

subprocess.HIGH_PRIORITY_CLASS

Параметр Popen creationflags, указывающий, что новый процесс будет иметь высокий приоритет.

Добавлено в версии 3.7.

subprocess.IDLE_PRIORITY_CLASS

Параметр Popen creationflags, указывающий, что новый процесс будет иметь наименьший приоритет простоя.

Добавлено в версии 3.7.

subprocess.NORMAL_PRIORITY_CLASS

Параметр Popen creationflags, указывающий, что новый процесс будет иметь нормальный приоритет. (дефолт)

Добавлено в версии 3.7.

subprocess.REALTIME_PRIORITY_CLASS

Параметр Popen creationflags, указывающий, что новый процесс будет иметь приоритет в реальном времени. Вы почти никогда не должны использовать REALTIME_PRIORITY_CLASS, так как это прерывает работу системных потоки, которые управляют вводом мыши, вводом с клавиатуры и сбросом диска в фоновом режиме. Этот класс может подходить для приложений, которые «разговаривают» непосредственно с аппаратными средствами или выполняют краткие задачи, которые должны иметь ограниченные прерывания.

Добавлено в версии 3.7.

subprocess.CREATE_NO_WINDOW

Параметр Popen creationflags, указывающий, что новый процесс не создаст окно.

Добавлено в версии 3.7.

subprocess.DETACHED_PROCESS

Параметр Popen creationflags, указывающий, что новый процесс не наследует родительскую консоль. Этот значение нельзя используемый с CREATE_NEW_CONSOLE.

Добавлено в версии 3.7.

subprocess.CREATE_DEFAULT_ERROR_MODE

Параметр Popen creationflags, указывающий, что новый процесс не наследует режим ошибок вызывающего процесса. Вместо этого новый процесс получает режим ошибок по умолчанию. Эта функция особенно полезна для многопоточных приложений оболочки, которые работают с отключенными жесткими ошибками.

Добавлено в версии 3.7.

subprocess.CREATE_BREAKAWAY_FROM_JOB

Параметр Popen creationflags, указывающий, что новый процесс не связан с заданием.

Добавлено в версии 3.7.

Старый высокоуровневый API

До Python 3.5 эти три функции включали API высокого уровня для подпроцессы. Теперь можно использовать run() во многих случаях, но многие существующие код вызывают эти функции.

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)

Выполнить команду, описанную args. Дождаться завершения команды, а затем возвращает returncode атрибут.

Код, необходимый для записи stdout или stderr, должен использовать run():

run(...).returncode

Для подавления stdout или stderr введите значение DEVNULL.

Приведенные выше аргументы являются лишь некоторыми общими. Полная сигнатура функции аналогична функции конструктора Popen - эта функция передает через этот интерфейс все поставляемые аргументы, кроме timeout.

Примечание

Не используйте stdout=PIPE или stderr=PIPE с этой функцией. Дочерний процесс блокируется, если он генерирует достаточно выходных данных для пайп, чтобы заполнить буфер пайп оС, так как пайпы не считываются из.

Изменено в версии 3.3: timeout было добавлено.

subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)

Выполнить команду с аргументами. Дождаться завершения команды. Если возвращает код был равен нулю, то возвращает, иначе поднять CalledProcessError. Объект CalledProcessError будет иметь возвращает код в returncode атрибут.

Код, необходимый для записи stdout или stderr, должен использовать run():

run(..., check=True)

Для подавления stdout или stderr введите значение DEVNULL.

Приведенные выше аргументы являются лишь некоторыми общими. Полная сигнатура функции аналогична функции конструктора 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=None, timeout=None, text=None, **other_popen_kwargs)

Выполнить команду с аргументами и возвращает ее вывод.

Если возвращает код было ненулевым, это приводит к CalledProcessError. Объект CalledProcessError будет иметь возвращает код в returncode атрибут и любые выходные данные в output атрибут.

Эквивалентно:

run(..., check=True, stdout=PIPE).stdout

Приведенные выше аргументы - лишь некоторые общие. Полная сигнатура функции во многом такая же, как и у run() - большинство аргументов передаются напрямую в этот интерфейс. Существует одно отклонение API от поведения run(): передача input=None будет вести себя так же, как input=b'' (или input='', в зависимости от других аргументов), вместо использования стандартного дескриптора входного файла родителя.

По умолчанию эта функция возвращает данные в виде кодированный байт. Фактическое кодировка выходных данных может зависеть от вызываемой команды, поэтому декодирование текста часто необходимо обрабатывать на уровне приложения.

Это поведение может быть переопределено путем установки text, encoding, errors или universal_newlines на True, как описано в Часто используемые аргументы и run().

Чтобы также зафиксировать стандартную ошибку в результате, используйте stderr=subprocess.STDOUT:

>>> subprocess.check_output(
...     "ls non_existent_file; exit 0",
...     stderr=subprocess.STDOUT,
...     shell=True)
'ls: non_existent_file: No such file or directory\n'

Добавлено в версии 3.1.

Изменено в версии 3.3: timeout было добавлено.

Изменено в версии 3.4: Добавлена поддержка аргумента input ключевой.

Изменено в версии 3.6: Были добавлены encoding и errors. Дополнительные сведения см. в разделе run().

Добавлено в версии 3.7: text был добавлен в качестве более читаемого алиас для universal_newlines.

Замена старых функций модуля subprocess

В этом разделе «a становится b» означает, что b может быть используемый в качестве замены для a.

Примечание

Все функции «a» в этом разделе завершаются неуспешно (более или менее), если не удается найти выполненную программу; замены «b» вызывают OSError.

Кроме того, замены с использованием check_output() завершатся сбоем с CalledProcessError, если запрошенная операция приведет к ненулевому возвращает код. Выходные данные по-прежнему доступны в качестве output атрибут возникшего исключения.

В следующих примерах предполагается, что соответствующие функции уже импортированы из модуля subprocess.

Замена команды /bin/sh оболочки

output=$(mycmd myarg)

становится:

output = check_output(["mycmd", "myarg"])

Замена пайпа оболочки

output=$(dmesg | grep hda)

становится:

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Разрешить 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)

Замена 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)

Замена семейства os.spawn

Пример P_NOWAIT:

pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
==>
pid = Popen(["/bin/mycmd", "myarg"]).pid

Пример P_WAIT:

retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==>
retcode = call(["/bin/mycmd", "myarg"])

Векторный пример:

os.spawnvp(os.P_NOWAIT, path, args)
==>
Popen([path] + args[1:])

Пример окружающей среды:

os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
==>
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})

Замена os.popen(), 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")

Замена функций из модуля 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.

Функции вызова устаревшей оболочки

Модуль также предоставляет следующие устаревшие функции из модуля 2.x commands. Эти операции неявно вызывают оболочку системы, и ни одна из описанных выше гарантий в отношении безопасности и непротиворечивости обработки исключений не действительна для этих функций.

subprocess.getstatusoutput(cmd)

Возвращает (exitcode, output) выполнения cmd в оболочке.

Выполнить строка cmd в оболочке с Popen.check_output() и возвращает 2-кортежный (exitcode, output). locale кодировка является используемый; для получения дополнительной информации см. примечания к Часто используемые аргументы.

Завершающая новая линия удаляется из выходных данных. код выхода для команды можно интерпретировать как возвращает код подпроцессы. Пример:

>>> 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, '')

Availability: 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'

Availability: POSIX & Windows.

Изменено в версии 3.3.4: Добавлена поддержка Windows

Примечания

Преобразование последовательности аргументов в строку в Windows

В Windows последовательность args преобразуется в строка, который может быть проанализирован с помощью следующих правил (которые соответствуют правилам, используемый во среде выполнения MS C):

  1. Аргументы разделяются пробелом, который является пробелом или табуляцией.
  2. Строка, окруженный двойными кавычками, интерпретируется как единственный аргумент, независимо от пробела, содержащегося внутри. Приведенный строка может быть встроен в аргумент.
  3. Двойная кавычка, которой предшествует обратная косая черта, интерпретируется как литерал двойная кавычка.
  4. Обратные косые черты интерпретируются буквально, если они непосредственно не предшествуют двойной кавычке.
  5. Если обратная косая черта непосредственно предшествует двойной кавычке, каждая пара обратной косой черты интерпретируется как литерал обратная косая черта. Если число обратных косых черт является нечетным, то последняя обратная косая черта уходит от следующей двойной кавычки, как описано в правиле 3.

См.также

shlex
Модуль предоставляет функцию для анализа и экранирования командных строк.