Альтернатива на основе модуля subprocess

alternativa na osnove modulya subprocess Системные инструменты

Как уже говорилось, в последних версиях Python появился модуль subprocess, позволяющий добиться того же эффекта, что и функции os.system и os.popen. Вообще говоря, для этого придется написать дополнительный программный код, но этот модуль обеспечивает более полный контроль над подключением и использованием потоков ввода- вывода. Это особенно полезно для реализации сложных схем связывания потоков ввода-вывода.

Например, чтобы запустить простую команду оболочки, как мы делали это с помощью функции os.system выше, можно воспользоваться функцией call из нового модуля, которая действует похожим образом (чтобы запустить такую команду, как type, встроенную в оболочку Windows, требуется соблюсти дополнительные условия, хотя для запуска обычных выполняемых файлов, таких как python, этого не требуется):

>  >> import subprocess

>  >> subprocess.call(‘python helloshell.py’) # напоминает os.system() The Meaning of Life

0

>  >> subprocess.call(‘cmd /C “type helloshell.py”’) # встроенная команда

>  a Python program

print(‘The Meaning of Life’)

0

>  >> subprocess.call(‘type helloshell.py’, shell=True) # альтернативный способ

>  a Python program # для встроенных команд

print(‘The Meaning of Life’)

0

Обратите внимание на аргумент shell=True в последнем вызове. Это платформозависимая особенность:

     Чтобы запустить встроенную команду оболочки в Windows, инструментам модуля subprocess, таким как call и Popen (об этой функции будет рассказываться ниже), необходимо передавать аргумент shell=True. Команды Windows, такие как type, требуют соблюдения дополнительных условий, но для запуска обычных выполняемых файлов, таких как python, этого не требуется.

     В Unix-подобных платформах, когда аргумент shell принимает значение False (по умолчанию), команда запускается непосредственно вызовом функции os.execvp, с которой мы встретимся в главе 5. Если в этом аргументе передать True, команда будет выполнена с помощью оболочки, при этом вы можете указать используемую оболочку в дополнительном аргументе.

Подробнее о некоторых из этих особенностей мы поговорим ниже, а пока достаточно будет запомнить, что в Unix-подобных системах вам может потребоваться передавать аргумент shell=True в некоторых примерах в этом разделе и в книге, если они предполагают использование таких особенностей оболочки, как путь поиска программ. Поскольку я запускаю примеры в Windows, этот аргумент я часто буду опускать.

Помимо имитации функции os.system, мы точно так же можем использовать этот модуль для имитации функции os.popen, чтобы запускать команды оболочки и получать ее вывод в нашем сценарии:

>>> pipe = subprocess.Popen(‘python helloshell.py’, stdout=subprocess.PIPE)

>>> pipe.communicate()

(b’The Meaning of Life\r\n’, None)

>>> pipe.returncode

0

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

>>> pipe = subprocess.Popen(‘python helloshell.py’, stdout=subprocess.PIPE)

>>> pipe.stdout.read()

b’The Meaning of Life\r\n’

>>> pipe.wait()

0

Фактически существует возможность прямой замены вызова os.popen объектом subprocess.Popen:

>  >> from subprocess import Popen, PIPE

>  >> Popen(‘python helloshell.py’, stdout=PIPE).communicate()[0] b’The Meaning of Life\r\n’

>>> 

>  >> import os

>  >> os.popen(‘python helloshell.py’).read()

The Meaning of Life\n

Как видите, реализация относительно простых случаев с помощью модуля subprocess требует дополнительной работы. Но ситуация меняется в лучшую сторону, когда возникает необходимость гибкого управления потоками ввода-вывода. Фактически, благодаря возможности обрабатывать стандартные потоки вывода и ошибок команды похожими способами, модуль subprocess в Python 3.X заменил оригинальные функции os.popen2, os.popen3 и os.popen4, имевшиеся в Python 2.X. Теперь эти функции являются лишь частными случаями использования интерфейса объектов модуля subprocess. Поскольку в более сложных случаях использования этого модуля предполагается взаимодействие со стандартными потоками ввода-вывода, мы отложим дальнейшее обсуждение этого модуля, пока не познакомимся с механизмом перенаправления потоков в следующей главе.

Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий