Документация Python неофициальный перевод
Содержание страницы

subprocess – Управление подпроцессамиsubprocess – Subprocess management

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


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

os.system
os.spawn*

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

См. также

PEP 324 – PEP, предлагающий модуль подпроцесса

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

Рекомендуемый способ вызова подпроцессов – использовать функцию 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() и, следовательно, на stdin дочернего процесса. При использовании он должен быть последовательностью байтов или строкой, если указаны encoding или errors, либо text равен true. При использовании внутренний объект Popen автоматически создаётся с stdin=PIPE, и аргумент stdin также не может быть использован.

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

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

Если env не равен None, он должен быть отображением (mapping), определяющим переменные окружения для нового процесса; они используются вместо поведения по умолчанию, заключающегося в наследовании окружения текущего процесса. Он передается напрямую в 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.

Изменено в версии 3.7.17: Изменён порядок поиска в оболочке Windows для shell=True. Текущий каталог и %PATH% заменены на %COMSPEC% и %SystemRoot%\System32\cmd.exe. В результате размещение вредоносной программы с именем cmd.exe в текущем каталоге больше не сработает.

class subprocess.CompletedProcess

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

args

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

returncode

Статус выхода дочернего процесса. Обычно статус выхода 0 указывает на успешное завершение.

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

stdout

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

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

stderr

Захваченный stderr дочернего процесса. Последовательность байтов или строка, если run() был вызван с указанием encoding, errors или 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 и указывает, что должен быть открыт канал (pipe) для стандартного потока. Наиболее полезен с Popen.communicate().

subprocess.STDOUT

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

exception subprocess.SubprocessError

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

Новое в версии 3.3.

exception subprocess.TimeoutExpired

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

cmd

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

timeout

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

output

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

stdout

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

stderr

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

Новое в версии 3.3.

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

exception subprocess.CalledProcessError

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

returncode

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

cmd

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

output

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

stdout

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

stderr

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

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

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

Чтобы поддерживать широкий спектр сценариев использования, конструктор 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.

Конструктор PopenPopen Constructor

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

class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=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) # Успешно!

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

На Windows, если args – последовательность, она будет преобразована в строку способом, описанным в разделе Преобразование последовательности аргументов в строку на Windows. Это связано с тем, что базовая функция CreateProcess() работает со строками.

Аргумент 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.7.17: Изменён порядок поиска в оболочке Windows для shell=True. Текущий каталог и %PATH% заменены на %COMSPEC% и %SystemRoot%\System32\cmd.exe. В результате размещение вредоносной программы с именем cmd.exe в текущем каталоге больше не сработает.

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

Если preexec_fn задан как вызываемый объект, этот объект будет вызван в дочернем процессе непосредственно перед его выполнением. (Только POSIX)

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

Параметр preexec_fn небезопасно использовать при наличии потоков в приложении. Дочерний процесс может зависнуть до вызова exec. Если его всё же нужно использовать, пусть он будет тривиальным! Сведите к минимуму количество вызываемых библиотек.

Примечание

Если нужно изменить окружение для дочернего процесса, используйте параметр env вместо изменения в preexec_fn. Параметр start_new_session может заменить ранее распространённое использование preexec_fn для вызова os.setsid() в дочернем процессе.

Если close_fds равен true, все файловые дескрипторы, кроме 0, 1 и 2, будут закрыты перед выполнением дочернего процесса. В противном случае, когда 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 может быть объектом str и путь-подобным. В частности, функция ищет executable (или первый элемент в args) относительно cwd, если путь к исполняемому файлу является относительным.

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

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

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

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

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

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

Примечание

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

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

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

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

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

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

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

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

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

ИсключенияExceptions

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

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

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

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

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

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

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

Вопросы безопасностиSecurity Considerations

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

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

Объекты PopenPopen Objects

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

Popen.poll()

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

Popen.wait(timeout=None)

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

Если процесс не завершается через тайм-аут секунд, возбуждается исключение TimeoutExpired. Это исключение можно безопасно перехватить и повторить ожидание.

Примечание

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

Примечание

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

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

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

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

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

Обратите внимание: если вы хотите отправить данные в stdin процесса, необходимо создать объект Popen с stdin=PIPE. Аналогично, чтобы получить что-то, кроме None, в результирующем кортеже, нужно также передать stdout=PIPE и/или stderr=PIPE.

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

Дочерний процесс не уничтожается по истечении тайм-аута, поэтому для корректной очистки хорошо написанное приложение должно уничтожить дочерний процесс и завершить обмен данными:

proc = subprocess.Popen(...)
try:
    outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

Примечание

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

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

Popen.send_signal(signal)

Отправляет сигнал signal дочернему процессу.

Примечание

В Windows SIGTERM является псевдонимом для terminate(). CTRL_C_EVENT и CTRL_BREAK_EVENT можно отправлять процессам, запущенным с параметром creationflags, включающим CREATE_NEW_PROCESS_GROUP.

Popen.terminate()

Останавливает дочерний процесс. В POSIX-системах метод отправляет SIGTERM дочернему процессу. В Windows для остановки дочернего процесса вызывается функция Win32 API TerminateProcess().

Popen.kill()

Завершает дочерний процесс. В POSIX-системах функция отправляет SIGKILL дочернему процессу. В Windows kill() является псевдонимом для terminate().

Также доступны следующие атрибуты:

Popen.args

Аргумент args в том виде, в котором он был передан в Popen – последовательность аргументов программы или одна строка.

Новое в версии 3.3.

Popen.stdin

Если аргумент stdin был PIPE, этот атрибут является доступным для записи потоковым объектом, возвращаемым open(). Если были указаны аргументы encoding или errors или аргумент universal_newlines был True, поток является текстовым, в противном случае – байтовым. Если аргумент stdin не был PIPE, этот атрибут равен None.

Popen.stdout

Если аргумент stdout был PIPE, этот атрибут является доступным для чтения потоковым объектом, возвращаемым open(). Чтение из потока предоставляет вывод дочернего процесса. Если были указаны аргументы encoding или errors или аргумент universal_newlines был True, поток является текстовым, в противном случае – байтовым. Если аргумент stdout не был PIPE, этот атрибут равен None.

Popen.stderr

Если аргумент stderr был PIPE, этот атрибут является доступным для чтения потоковым объектом, возвращаемым open(). Чтение из потока предоставляет вывод ошибок дочернего процесса. Если были указаны аргументы encoding или errors или аргумент universal_newlines был True, поток является текстовым, в противном случае – байтовым. Если аргумент stderr не был PIPE, этот атрибут равен None.

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

Используйте communicate() вместо .stdin.write, .stdout.read или .stderr.read, чтобы избежать взаимоблокировок из-за переполнения буферов каналов ОС и блокировки дочернего процесса.

Popen.pid

PID дочернего процесса.

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

Popen.returncode

Код возврата дочернего процесса, устанавливаемый методами poll() и wait() (а косвенно – communicate()). Значение None указывает, что процесс ещё не завершён.

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

Вспомогательные классы Windows PopenWindows Popen Helpers

Класс 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 должно быть истинным, если последовательность непуста.

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

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

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

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

Константы WindowsWindows Constants

Модуль 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.

Старый высокоуровневый APIOlder high-level API

До Python 3.5 эти три функции представляли собой высокоуровневый API для subprocess. Теперь во многих случаях можно использовать 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.

Изменено в версии 3.7.17: Изменён порядок поиска в оболочке Windows для shell=True. Текущий каталог и %PATH% заменены на %COMSPEC% и %SystemRoot%\System32\cmd.exe. В результате размещение вредоносной программы с именем cmd.exe в текущем каталоге больше не сработает.

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.

Изменено в версии 3.7.17: Изменён порядок поиска в оболочке Windows для shell=True. Текущий каталог и %PATH% заменены на %COMSPEC% и %SystemRoot%\System32\cmd.exe. В результате размещение вредоносной программы с именем cmd.exe в текущем каталоге больше не сработает.

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() – большинство аргументов передаются напрямую этому интерфейсу. Однако явная передача input=None для наследования дескриптора стандартного ввода родительского процесса не поддерживается.

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

Это поведение можно переопределить, установив 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: New in version 3.7: text добавлен как более читаемый псевдоним для universal_newlines.

Изменено в версии 3.7.17: Изменён порядок поиска в оболочке Windows для shell=True. Текущий каталог и %PATH% заменены на %COMSPEC% и %SystemRoot%\System32\cmd.exe. В результате размещение вредоносной программы с именем cmd.exe в текущем каталоге больше не сработает.

Замена старых функций модулем subprocessReplacing Older Functions with the subprocess Module

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

Примечание

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

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

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

Замена обратного апострофа оболочки /bin/shReplacing /bin/sh shell backquote

output=`mycmd myarg`

становится:

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

Замена конвейера оболочкиReplacing shell pipeline

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()Replacing os.system()

sts = os.system("mycmd" + " myarg")
# становится
sts = call("mycmd" + " myarg", shell=True)

Примечания:

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

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

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

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

Пример P_NOWAIT:

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

Пример P_WAIT:

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

Пример с вектором:

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

Пример с окружением:

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

Замена os.popen(), os.popen2(), os.popen3()Replacing os.popen(), os.popen2(), os.popen3()

(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)
(child_stdin,
 child_stdout,
 child_stderr) = os.popen3(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin,
 child_stdout,
 child_stderr) = (p.stdin, p.stdout, p.stderr)
(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)

Обработка кода возврата выполняется следующим образом:

pipe = os.popen(cmd, 'w')
...
rc = pipe.close()
if rc is not None and rc >> 8:
    print("There were some errors")
==>
process = Popen(cmd, stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
    print("There were some errors")

Замена функций из модуля popen2Replacing functions from the popen2 module

Примечание

Если аргумент cmd функций popen2 является строкой, команда выполняется через /bin/sh. Если это список, команда выполняется напрямую.

(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
==>
p = Popen("somestring", shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)
(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
==>
p = Popen(["mycmd", "myarg"], bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)

popen2.Popen3 и popen2.Popen4 в основном работают как subprocess.Popen, за исключением того, что:

  • Popen вызывает исключение, если выполнение завершается неудачей.

  • Аргумент capturestderr заменяется аргументом stderr.

  • stdin=PIPE и stdout=PIPE должны быть указаны.

  • popen2 по умолчанию закрывает все файловые дескрипторы, но необходимо указать close_fds=True с Popen, чтобы гарантировать такое поведение на всех платформах или в старых версиях Python.

Устаревшие функции вызова оболочкиLegacy Shell Invocation Functions

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

subprocess.getstatusoutput(cmd)

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

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

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

>>> 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

ПримечанияNotes

Преобразование последовательности аргументов в строку в WindowsConverting an argument sequence to a string on Windows

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

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

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

  3. Двойная кавычка, перед которой стоит обратная косая черта, интерпретируется как литеральная двойная кавычка.

  4. Обратные косые черты интерпретируются буквально, если только они не стоят непосредственно перед двойной кавычкой.

  5. Если обратные косые черты стоят непосредственно перед двойной кавычкой, каждая пара обратных косых черт интерпретируется как литеральная обратная косая черта. Если количество обратных косых черт нечётное, последняя обратная косая черта экранирует следующую за ней двойную кавычку, как описано в правиле 3.

См. также

shlex

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