Spec-Zone.ru › Python 3.8

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.

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

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

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

Аргумент input передаётся в Popen.communicate() и, таким образом, в стандартный ввод дочернего процесса. Если используется, он должен быть последовательностью байтов или строкой, если заданы 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"])  # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

>>> subprocess.run(["ls", "-l", "/dev/null"], 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() вызывалась с кодировкой, ошибками или text=True. None если stdout не был захвачен.

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

stderr

Захваченный stderr из дочернего процесса. Последовательность байтов или строка, если run() вызывалась с кодировкой, ошибками или text=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

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

stderr

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

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

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

END_OF_DOCUMENT_MARKER
exception subprocess.CalledProcessError

Подкласс SubprocessError, генерируемый, когда процесс, запущенный с помощью check_call() или check_output(), возвращает код завершения, отличный от нуля.

returncode

Код завершения дочернего процесса. Если процесс завершился из-за сигнала, это будет отрицательный номер сигнала.

cmd

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

output

Выходные данные дочернего процесса, если они были получены функциями run() или check_output(). В противном случае, None.

stdout

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

stderr

Выходные данные stderr дочернего процесса, если они были получены функцией run(). В противном случае, None.

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

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

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

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

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

Если указаны encoding или errors, или text (также известный как 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.

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

Примечание

Атрибут 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 — т.е. в текстовом режиме)
  • любое другое положительное значение — использовать буфер примерно такого размера
  • отрицательное значение 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.

Изменено в версии 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 в дочернем процессе перед 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, или text равно true, объекты файлов stdin, stdout и stderr открываются в текстовом режиме с указанным encoding и errors, как описано выше в Часто используемые аргументы. Аргумент universal_newlines эквивалентен text и предоставляется для обратной совместимости. По умолчанию объекты файлов открываются в двоичном режиме.

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

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

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

  • CREATE_NEW_CONSOLE
  • CREATE_NEW_PROCESS_GROUP
  • ABOVE_NORMAL_PRIORITY_CLASS
  • BELOW_NORMAL_PRIORITY_CLASS
  • HIGH_PRIORITY_CLASS
  • IDLE_PRIORITY_CLASS
  • NORMAL_PRIORITY_CLASS
  • REALTIME_PRIORITY_CLASS
  • CREATE_NO_WINDOW
  • DETACHED_PROCESS
  • CREATE_DEFAULT_ERROR_MODE
  • CREATE_BREAKAWAY_FROM_JOB

Объекты 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 Subsystem for Linux и QEMU User Emulation, конструктор 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 injection.

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

Объекты Popen

Экземпляры класса Popen имеют следующие методы:

Popen.poll()

Проверить, завершил ли дочерний процесс свою работу. Устанавливает и возвращает атрибут returncode. В противном случае, возвращает None.

Popen.wait(timeout=None)

Подождать завершения дочернего процесса. Устанавливает и возвращает атрибут returncode.

Если процесс не завершится после timeout секунд, будет поднято исключение TimeoutExpired. Безопасно перехватывать это исключение и повторно пытаться выполнить ожидание.

Примечание

Это приведёт к тупиковой ситуации при использовании stdout=PIPE или stderr=PIPE и дочерний процесс генерирует достаточно вывода в канал, так что он заблокируется, ожидая, пока буфер канала операционной системы примет больше данных. Используйте Popen.communicate() при использовании каналов, чтобы избежать этого.

Примечание

Функция реализована с использованием цикла busy-wait (неблокирующий вызов и короткие паузы). Используйте модуль asyncio для асинхронного ожидания: см. asyncio.create_subprocess_exec.

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

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

Взаимодействие с процессом: Отправка данных в стандартный ввод. Чтение данных из стандартного вывода и стандартной ошибки, пока не будет достигнут конец файла. Дожидаться завершения процесса и установить атрибут returncode. Необязательный аргумент input должен содержать данные, которые нужно отправить дочернему процессу, или None, если данные не нужно отправлять. Если потоки были открыты в текстовом режиме, input должен быть строкой. В противном случае это байты.

communicate() возвращает кортеж (stdout_data, stderr_data). Данные будут строками, если потоки были открыты в текстовом режиме; в противном случае это байты.

Обратите внимание, что если вы хотите отправить данные в стандартный ввод процесса, вам необходимо создать объект 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

Идентификатор процесса (PID) дочернего процесса.

Обратите внимание, что если вы установили аргумент shell в True, это PID запущенной оболочки.

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.

END_OF_DOCUMENT_MARKER

Константы 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 для создания новой группы процессов. Этот флаг необходим для использования os.kill() для дочернего процесса.

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

subprocess.ABOVE_NORMAL_PRIORITY_CLASS

Параметр Popen для задания повышенного приоритета нового процесса.

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

subprocess.BELOW_NORMAL_PRIORITY_CLASS

Параметр Popen для задания пониженного приоритета нового процесса.

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

subprocess.HIGH_PRIORITY_CLASS

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

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

subprocess.IDLE_PRIORITY_CLASS

Параметр Popen для задания приоритета нового процесса в режиме ожидания (низкий).

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

subprocess.NORMAL_PRIORITY_CLASS

Параметр Popen для задания нормального приоритета нового процесса (по умолчанию).

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

subprocess.REALTIME_PRIORITY_CLASS

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

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

subprocess.CREATE_NO_WINDOW

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

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

subprocess.DETACHED_PROCESS

Параметр Popen для задания отсутствия наследования консоли родительского процесса. Это значение не может быть использовано вместе с CREATE_NEW_CONSOLE.

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

subprocess.CREATE_DEFAULT_ERROR_MODE

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

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

subprocess.CREATE_BREAKAWAY_FROM_JOB

Параметр Popen для задания отсутствия связи нового процесса с задачей.

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

END_OF_DOCUMENT_MARKER

Старые высокоуровневые 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()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]

Вызов p1.stdout.close() после запуска p2 важен, чтобы p1 получил SIGPIPE, если p2 завершится до p1.

В качестве альтернативы, для надёжного ввода, можно напрямую использовать собственную поддержку конвейеров оболочки:

output=$(dmesg | grep hda)

становится:

output=check_output("dmesg | grep hda", shell=True)

Замена os.system()

sts = os.system("mycmd" + " myarg")
# becomes
sts = call("mycmd" + " myarg", shell=True)

Примечания:

  • Вызов программы через оболочку обычно не требуется.

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

try:
    retcode = call("mycmd" + " myarg", shell=True)
    if retcode < 0:
        print("Child was terminated by signal", -retcode, file=sys.stderr)
    else:
        print("Child returned", retcode, file=sys.stderr)
except OSError as e:
    print("Execution failed:", e, file=sys.stderr)

Замена семейства функций 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.
END_OF_DOCUMENT_MARKER

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

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

subprocess.getstatusoutput(cmd)

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

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

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

>>> subprocess.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')
>>> subprocess.getstatusoutput('cat /bin/junk')
(1, 'cat: /bin/junk: No such file or directory')
>>> subprocess.getstatusoutput('/bin/junk')
(127, 'sh: /bin/junk: not found')
>>> subprocess.getstatusoutput('/bin/kill $$')
(-15, '')

Доступность: POSIX & Windows.

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

Функция теперь возвращает (exitcode, output) вместо (status, output), как это было в Python 3.3.3 и ранее. exitcode имеет то же значение, что и returncode.

subprocess.getoutput(cmd)

Возвращает вывод (stdout и stderr) выполнения cmd в оболочке.

Подобно getstatusoutput(), за исключением того, что код завершения игнорируется, а возвращаемое значение — строка, содержащая вывод команды. Пример:

>>> subprocess.getoutput('ls /bin/ls')
'/bin/ls'

Доступность: POSIX & Windows.

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

Примечания

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

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

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

См. также

shlex

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

© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.8/library/subprocess.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API