Запуск процессов и выполнение внешних команд в python

В питоне есть модуль subprocess который предоставляет средства запуска внешних процессов и выполнения команд оболочки.

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

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

Примечание: вызов run без параметра shell полностью эквивалентен вызову функции call(), которая возвращает только код возврата. Передача аргумента check=True, создает из run, полный аналог функции check_call().

Аналогично с командой оболочки работает и функция os.system, которой в качестве параметра передается вся команда которая должна быть выполнена вместе с параметрами.

В случае необходимости получения потока вывода, программы или команды, необходимо задать функции параметр stdout:

Аналогичное поведение имеет и более низкоуровневая функция popen из модуля os:

Примечание: вызов run с check=True и stdout=subprocess.PIPE, создает из run, полный аналог функции check_output().

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

Если вывод команды нужно подавить, то тогда вместо PIPE надо указать subprocess.DEVNULL.

Класс Popen

Класс Popen является оболочкой вокруг функции os.popen. Для получения вывода используется класс которому коме команды передается также атрибут stdout:

Здесь мы связали поток стандартного вывода команды оболочки с каналом и вызвали метод communicate, ожидающий завершения команды и принимающий текст, который она выводит в стандартный поток вывода и в стандартный поток ошибок. Код завершения команды доступен в виде атрибута, после того как она будет выполнена. Это полный аналог функции popen стой лишь разницей, что выводом управляет экземпляр Popen.

Точно так же мы могли бы использовать отдельную функцию чтения потока стандартного вывода команды и отдельную функцию ожидания ее завершения (которая возвращает код завершения):

Передача потока в программу

Что бы выполнить запись Popen надо настроить следующим образом:

Что бы отправить данные в канал их требуется передать методы communicate.

Возможен вариант двухстороннего взаимодействия:

Перехват всех трех каналов ввода-вывода (ввод, вывод и канал ошибок), делается вызовом  похожим на вызов popen3():

Иногда необходимо объединить вывод stdout и stderr, что можно сделать командой:

ПРИМЕЧАНИЕ: Инструкция на языке Python exec(open(file).read()) тоже выполняет код программного файла, но внутри того же процесса, который ее вызвал. В этом отношении она похожа на операцию импортирования, но по своему действию она больше похожа на операцию вставки содержимого файла в вызывающую программу в том месте, где стоит вызов exec (если явно не передаются словари глобального или локального пространства имен).
В отличие от операции импортирования, функция exec читает и выполняет программный код файла без всяких проверок (один и тот же файл можно выполнить несколько раз в одном процессе); при выполнении файла не создается объект модуля; и, если функции явно не передаются словари пространств имен, операции присваивания в программном коде файла могут затирать переменные в области видимости, где находится вызов exec. 

Обсуждение закрыто.