Выполнение команд оболочки с Python
Поскольку в задачи системный администратор все время включает команды Linux, выполнение команд Linux из скрипта Python является отличной помощью.
В этой статье мы покажем вам пару способов, которыми вы можете запускать команды оболочки и получать их вывод в своей программе Python.
Выполнить команду Shell в Python с модулем os
Позвольте нам создать простую программу на Python, которая выполняет команду оболочки с модулем os.
Теперь, если мы запускаем эту программу, и вот что мы видим в выводе.
Это содержимое каталога, в котором хранится myprog.py.
Если вы хотите использовать вывод команды оболочки, вы можете сохранить его в файле непосредственно из команды оболочки:
Вы также можете сохранить выходные данные команды оболочки в переменной следующим образом:
Если вы запустите вышеупомянутую программу, она напечатает содержимое переменной myCmd и будет такой же, как и результат команды ls, которую мы видели ранее.
Теперь давайте посмотрим другой способ запуска команды Linux в Python.
Выполнить команду оболочки в Python с модулем подпроцесса
Несколько лучший способ запуска команд оболочки в Python – использование подпроцессмодуль.
Если вы хотите запустить команду оболочки без каких-либо параметров и аргументов, вы можете вызвать подпроцесс следующим образом:
Метод call выполнит команду оболочки. Вы увидите содержимое текущего рабочего каталога при запуске программы:
Если вы хотите предоставить опции и аргументы вместе с командой оболочки, вам придется предоставить их в виде списка.
Когда вы запустите программу, вы увидите содержимое текущего каталога в виде списка.
Теперь, когда вы знаете, как запустить команду оболочки с подпроцессом, возникает вопрос о сохранении вывода команды оболочки.
Для этого вам нужно будет использовать функцию Popen. Он выводит объект Popen, у которого есть метод communication(), который можно использовать для получения стандартного вывода и ошибки в виде кортежа.
Когда вы запустите программу, вы увидите stdout и stderr (которых в данном случае нет).
Мы надеемся, что этот быстрый совет помог вам выполнить команду оболочки в программах Python. Если у вас есть вопросы или предложения, пожалуйста, не стесняйтесь оставить комментарий ниже.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Python | Выполнять и анализировать команды Linux
Linux является одной из самых популярных операционных систем и распространенным выбором для разработчиков. Он популярен, потому что это открытый исходный код, он бесплатный и настраиваемый, он очень надежный и адаптируемый.
Операционная система в основном состоит из двух частей: ядра и оболочки. Ядро в основном управляет связью между программным обеспечением и оборудованием. Оболочка принимает входные данные или команды от пользователя и выдает выходные данные. В настоящее время в большинстве дистрибутивов Linux используется оболочка BASH (оболочка Bourne again). Команды и сценарии оболочки очень мощные и часто используются разработчиками.
В этой статье мы рассмотрим выполнение и анализ команд Linux с использованием python.
Подпроцесс —
Подпроцесс — это модуль в Python, который позволяет нам запускать новые приложения или процессы в Python. Этот модуль предназначен для замены нескольких старых модулей в Python. Мы можем использовать этот модуль для запуска других программ или выполнения команд Linux.
Начиная процесс —
Новый процесс может быть запущен с помощью функции Popen, определенной в модуле подпроцесса. Это конструктор для класса Popen, который принимает аргументы для настройки нового процесса. Основной процесс создания и управления в этом модуле обрабатывается классом Popen.
Аргументы:
- The first parameter is a list that contains the commands and their options if any.
ex: [‘ls’, ‘-l’]
the above example is equivalent to typing ‘ls -l’ in the terminal- The second parameter is the stdout value. it specifies the standard output.
ex: stdout = subprocess.PIPE
This indicates that a new pipe or redirection should be created. The default value is
“None”, which means that no redirection will occur.
Мы можем получить выходные данные команды, используя функцию связи . Он читает данные из stdout и stderr, пока не достигнет конца файла, и ожидает завершения процесса. Он возвращает кортеж, который содержит выходные данные и ошибку, если таковые имеются.
Синтаксис:
Выход выполненной команды сохраняется в данных. Используя эти функции, мы можем выполнять команды Linux и получать их вывод.
Список каталогов —
Мы можем использовать команду «ls» с такими параметрами, как «-l», «-al» и т. Д., Чтобы вывести список всех файлов в текущем каталоге. Затем мы можем проанализировать этот вывод и распечатать его в презентабельном формате. Функция get_permissions() анализирует выходные данные команды list и извлекает только имена файлов и их соответствующие разрешения.
# функция для перечисления файлов в
# текущий каталог и
# разбирать вывод.
def list_command(args = ‘-l’ ):
# используя функцию Popen для выполнения
# команда и сохранить результат в темп.
# возвращает кортеж, содержащий
# данные и ошибка, если есть.
temp = subprocess.Popen([cmd, args], stdout = subprocess.PIPE)
# мы используем функцию связи
# чтобы получить вывод
output = str (temp.communicate())
# разделить вывод так, чтобы
# мы можем разобрать их построчно
output = output.split( «\n» )
output = output[ 0 ].split( ‘\\’ )
# переменная для хранения вывода
for line in output:
for i in range ( 1 , len (res) — 1 ):
# анализировать вывод ls
# команда и получить разрешения
# файлов и хранить их в
# текстовый файл.
res = list_command( ‘-l’ )
# перебрать все строки
# и получить имя файла
for i in range ( 1 , len (res) — 1 ):
folder_name = line[ len (line) — 1 ]
permission_value = line[ 0 ]
# создать каталог с именем
# выходы для хранения выходных файлов
# открыть выходной файл
out = open ( ‘permissions.txt’ , ‘w’ )
out.write( ‘Folder Name Permissions\n\n’ )
# запись в выходной файл
for folder in permissions:
out.write(folder + ‘ : ‘ + permissions[folder] + ‘\n’ )
if __name__ = = ‘__main__’ :
Выход :
Команда пинга —
Команда ping расшифровывается как Packet Internet Groper. Чаще всего он используется для проверки связи между двумя системами или узлами. Используя команду ping, мы можем проверить работоспособность соединения между одним узлом или другим. Он обменивается пакетами данных между двумя узлами, а также рассчитывает время прохождения туда-обратно.
# функция для проверки связи с данным хостом
# отправить два пакета данных на хост
temp = subprocess.Popen([cmd, ‘-c 2’ , host], stdout = subprocess.PIPE)
# получить вывод команды ping
output = str (temp.communicate())
output = output.split( «\n» )
output = output[ 0 ].split( ‘\\’ )
# переменная для хранения результата
for line in output:
print ( ‘ping results: ‘ )
print ( ‘\n’ .join(res[ len (res) — 3 : len (res) — 1 ]))
if __name__ = = ‘__main__’ :
Выход :
Изменение разрешений —
Команда chmod может использоваться для изменения прав доступа к файлу. Это сокращение от режима изменения. Более подробную информацию можно найти здесь
# функция для изменения разрешений
# данного файла
def change_permissions(args, filename):
data = subprocess.Popen([ls, ‘-l’ , filename], stdout = subprocess.PIPE)
output = str (data.communicate())
print ( ‘file permissions before chmod % s: ‘ % (args))
# выполнение chmod для указанного файла
temp = subprocess.Popen([cmd, args, filename], stdout = subprocess.PIPE)
data = subprocess.Popen([ls, ‘-l’ , filename], stdout = subprocess.PIPE)
output = str (data.communicate())
# печать разрешений после chmod
print ( ‘file permissions after chmod % s: ‘ % (args))
if __name__ = = ‘__main__’ :
# изменение разрешений ‘sample.txt’
change_permissions( ‘755’ , ‘sample.txt’ )
Выход :
Выполнение shell команд с Python
Повторяющиеся задачи созрели для автоматизации. Разработчики и системные администраторы обычно автоматизируют рутинные задачи, такие как проверки работоспособности и резервное копирование файлов, с помощью сценариев оболочки. Однако, поскольку эти задачи становятся более сложными, сценарии оболочки могут усложняться в обслуживании.
К счастью, мы можем использовать Python вместо сценариев оболочки для автоматизации. Python предоставляет методы для запуска команд оболочки, предоставляя нам ту же функциональность, что и сценарии оболочки. Изучение того, как выполнять команды оболочки в Python, открывает нам возможность автоматизировать компьютерные задачи структурированным и масштабируемым образом.
В этой статье мы рассмотрим различные способы выполнения команд оболочки в Python и идеальную ситуацию для использования каждого метода.
Использование os.system для запуска команды
Python позволяет нам немедленно выполнить команду оболочки, которая хранится в строке, используя функцию os.system() .
Давайте начнем с создания нового файла Python с именем echo_adelle.py и введите следующее:
Первое, что мы делаем в нашем Python файле, это импортируем модуль os , который содержит функцию system , которая может выполнять команды оболочки. Следующая строка делает именно это, запускает команду echo в нашей оболочке через Python.
В вашем терминале запустите этот файл с помощью следующей команды, и вы должны увидеть соответствующий вывод:
По мере того, как команды echo выводятся в наш stdout , os.system() также возвращает код завершения команды оболочки. Код 0 означает, что он работает без проблем, а любое другое число означает ошибку.
Давайте создадим новый файл с именем cd_return_codes.py и введите следующее:
В этом сценарии мы создаем две переменные, в которых хранятся результаты выполнения команд, которые изменяют каталог на домашнюю папку и на несуществующую папку. Запустив этот файл, мы увидим:
Первая команда, которая изменяет каталог на домашний каталог, выполняется успешно. Следовательно, os.system() возвращает код ноль, который хранится в home_dir . С другой стороны, unknown_dir сохраняет код завершения неудачной команды bash, чтобы изменить каталог на несуществующую папку.
Функция os.system() выполняет команду, печатает любой вывод команды на консоль и возвращает код завершения команды. Если нам нужно более детальное управление вводом и выводом команды оболочки в Python, мы должны использовать модуль subprocess .
Выполнение команды с подпроцессом
Модуль subprocess — это рекомендуемый Python способ выполнения команд оболочки. Это дает нам гибкость для подавления вывода команд оболочки или цепочки входов и выходов различных команд вместе, в то же время обеспечивая аналогичный опыт os.system() для базовых сценариев использования.
В новом файле с именем list_subprocess.py напишите следующий код:
В первой строке мы импортируем модуль subprocess , который является частью стандартной библиотеки Python. Затем мы используем функцию subprocess.run() для выполнения команды. Также как и команда os.system() , subprocess.run() возвращает код того, что было выполнено.
Обратите внимание, что subprocess.run() принимает список строк в качестве входных данных вместо одной строки. Первым элементом списка является название команды. Остальные пункты списка — это флаги и аргументы команды.
Примечание: Как правило, вам нужно отделить аргументы , основанные на пространстве, например , ls -alh будет [«ls», «-alh»] , а ls -a -l -h , превратится в [«ls», «-a», -«l», «-h»] .
Запустите этот файл, и вывод вашей консоли будет похож на:
Теперь давайте попробуем использовать одну из более продвинутых функций subprocess.run() , а именно игнорирование вывода в stdout . В том же файле list_subprocess.py измените:
Стандартный вывод команды теперь передается на специальное устройство /dev/null , что означает, что вывод не будет отображаться на наших консолях. Запустите файл в вашей оболочке, чтобы увидеть следующий вывод:
Что если мы хотим получить результат команды? subprocess.run() поможет сделать это. Создайте новый файл с именем cat_subprocess.py , набрав следующее:
Мы используем довольно много параметров, давайте рассмотрим их:
- stdout=subprocess.PIPE говорит Python перенаправить результат выполнения команды в объект, чтобы позже его можно было прочитать вручную
- text=True возвращает stdout и в stderr виде строк. Тип возвращаемого значения по умолчанию — байты.
- input=»Hello from the other side» говорит Python добавить строку в качестве ввода в команду cat .
Запуск этого файла приводит к следующему выводу:
Мы также можем бросить Exception без проверки значения возврата. В новом файле false_subprocess.py добавьте код ниже:
В вашем терминале запустите этот файл. Вы увидите следующую ошибку:
Используя check=True , мы сообщаем Python, что нужно вызывать любые исключения, если возникает ошибка. Так как мы столкнулись с ошибкой, оператор print в последней строке не был выполнен.
Функция subprocess.run() дает нам огромную гибкость. Эта функция представляет собой упрощенную абстракцию класса subprocess.Popen , которая предоставляет дополнительные функциональные возможности, которые мы можем исследовать.
Выполнение команды с Popen
Класс subprocess.Popen предоставляет больше возможностей для разработчика при взаимодействии с оболочкой. Тем не менее, мы должны быть более точными в получении результатов и ошибок
По умолчанию subprocess.Popen не останавливает обработку программы Python, если ее команда не завершила выполнение. В новом файле с именем list_popen.py введите следующее:
Этот код эквивалентен list_subprocess.py . Он запускает команду с помощью subprocess.Popen и ожидает ее завершения, прежде чем выполнить оставшуюся часть сценария Python.
Допустим, мы не хотим ждать завершения выполнения команды оболочки, чтобы программа могла работать над другими вещами. Как узнать, когда команда оболочки закончила выполнение?
Метод poll() возвращает код завершения, если команда закончит работу, или None если он все еще выполняется. Например, если бы мы хотели проверить, завершено ли list_dir , а не ждать его, у нас была бы следующая строка кода:
Для управления вводом и выводом subprocess.Popen нам нужно использовать метод communicate() .
В новый файл с именем cat_popen.py добавьте следующий фрагмент кода:
Метод communicate() принимает аргумент input , который используется для передачи входных данных команде оболочки. Метод communicate также возвращает stdout и stderr когда они установлены.
Мы рассмотрели три способа запуска команд оболочки в Python с использованием класса subprocess.Popen . Давайте еще раз рассмотрим их характеристики, чтобы узнать, какой метод лучше всего подходит для требований проекта.
Какой из них я должен использовать?
Если вам нужно выполнить одну или несколько простых команд и вам не помешает, если их вывод поступит в консоль, вы можете использовать команду os.system() . Если вы хотите управлять вводом и выводом команды оболочки, используйте subsystem.run() . Если вы хотите выполнить команду и продолжить выполнять другую работу, пока она выполняется, используйте subprocess.Popen .
Вот таблица с некоторыми различиями в юзабилити, которые вы также можете использовать для обоснования своего решения: