Поиск по сайту:
Последовательная смена людей есть один человек, пребывающий вечно (Б. Паскаль).

Выполнение команд оболочки с Python

21.01.2019

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

Поскольку в задачи системный администратор все время включает команды Linux, выполнение команд Linux из скрипта Python является отличной помощью.

В этой статье мы покажем вам пару способов, которыми вы можете запускать команды оболочки и получать их вывод в своей программе Python.

 

Выполнить команду Shell в Python с модулем os

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

import os 
myCmd = 'ls -la' 
os.system (myCmd)

 

Теперь, если мы запускаем эту программу, и вот что мы видим в выводе.

python myprog.py 
total 40
drwxr-xr-x  3 andreyex andreyex 4096 Jan 20 13:23 .
drwxr-xr-x 49 andreyex andreyex 4096 Jan 20 13:34 ..
-r--r--r--  1 andreyex andreyex  456 Dec 19 20:51 andreyex.txt
-rw-r--r--  1 andreyex andreyex    0 Jan 20 11:32 master
-rw-r--r--  1 andreyex andreyex   14 Jan 10 21:22 masterX.txt
-rw-r--r--  1 andreyex andreyex   14 Jan 10 12:17 destroyer.txt
--w-r--r--  1 andreyex andreyex  356 Jan 20 13:12 mytest.txt
-rw-r--r--  1 andreyex andreyex  356 Dec 24 15:18 login.txt
-rw-r--r--  1 andreyex andreyex   44 Jan 20 10:53 mymyprog.py
-rw-r--r--  1 andreyex andreyex  356 Dec 22 15:33 turbo.txt
drwxr-xr-x  3 andreyex andreyex 4096 Jan  3 20:51 target

 

Это содержимое каталога, в котором хранится myprog.py.

Если вы хотите использовать вывод команды оболочки, вы можете сохранить его в файле непосредственно из команды оболочки:

import os
myCmd = 'ls -la > out.txt'
os.system(myCmd)

 

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

import os
myCmd = os.popen('ls -la').read()
print(myCmd)

 

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

Теперь давайте посмотрим другой способ запуска команды Linux в Python.

 

Выполнить команду оболочки в Python с модулем подпроцесса

Несколько лучший способ запуска команд оболочки в Python — использование подпроцессмодуль.

Если вы хотите запустить команду оболочки без каких-либо параметров и аргументов, вы можете вызвать подпроцесс следующим образом:

import subprocess
subprocess.call("ls")

 

Метод call выполнит команду оболочки. Вы увидите содержимое текущего рабочего каталога при запуске программы:

python myprog.py 
agatha.txt  count1.txt    file1.txt  myprog.py   target
count        count2.txt  file2.txt  sherlock.txt

 

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

import subprocess
subprocess.call(["ls", "-l", "."])

 

Когда вы запустите программу, вы увидите содержимое текущего каталога в виде списка.

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

Для этого вам нужно будет использовать функцию Popen. Он выводит объект Popen, у которого есть метод communication(), который можно использовать для получения стандартного вывода и ошибки в виде кортежа.

import subprocess
MyOut = subprocess.Popen(['ls', '-l', '.'], 
            stdout=subprocess.PIPE, 
            stderr=subprocess.STDOUT)
stdout,stderr = MyOut.communicate()
print(stdout)
print(stderr)

 

Когда вы запустите программу, вы увидите stdout и stderr (которых в данном случае нет).

python myprog.py 
 total 32
 -r--r--r-- 1 andreyex andreyex  456 Dec 11 21:29 agatha.txt
 -rw-r--r-- 1 andreyex andreyex    0 Jan 20 12:11 count
 -rw-r--r-- 1 andreyex andreyex   14 Jan 10 16:12 count1.txt
 -rw-r--r-- 1 andreyex andreyex   14 Jan 10 16:12 count2.txt
 --w-r--r-- 1 andreyex andreyex  356 Jan 20 12:10 file1.txt
 -rw-r--r-- 1 andreyex andreyex  356 Dec 17 09:59 file2.txt
 -rw-r--r-- 1 andreyex andreyex  212 Jan 20 16:54 myprog.py
 -rw-r--r-- 1 andreyex andreyex  356 Dec 11 21:35 sherlock.txt
 drwxr-xr-x 3 andreyex andreyex 4096 Jan  4 20:10 target

None

 

Мы надеемся, что этот быстрый совет помог вам выполнить команду оболочки в программах Python. Если у вас есть вопросы или предложения, пожалуйста, не стесняйтесь оставить комментарий ниже.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (3 оценок, среднее: 5,00 из 5)
Загрузка...
Поделиться в соц. сетях:
5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest

**ссылки nofollow

6 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
kadyr

Есть ли возможность настроить взаимодействие python скрипта c консольным приложением linux

Денис

Добрый день, а можно попросить Вас написать код, который будет запускать tcpdump контролирующий наличие трафика на UDP порту. Как трафик появился, написать в консоли 1, как трафик на порту пропал — написать 2. Мониторинг должен проводиться постоянно.

Денис

Спасибо за ответ.
Еще не пробовал запустить код, но не вижу вывода «2» если трафик пропал. Сейчас попробую пояснить зачем мне нужен код.
Есть два сервиса, один отправляет в другой по udp аудиотрафик, второй анализирует этот трафик и отдает его дальше, но есть нюанс, анализ трафика проходит неверно в конце из-за неожиданного прерывания трафика, когда первый сервис перестает его транслировать. Есть возможность помочь обработке, во втором (анализирующем сервисе) есть возможность указывать начало анализа и его конец через псевдоустройство PTY. Если В начале трансляции мы на это устройство отправим «1» а когда трафик пропадет «2», то сможем предотвратить неверную обработку.
В итоге нужна примочка на питоне, которая всегда будет контролировать наличие трафика, и когда трафик появится — отправит в PTY_PATH=/tmp/sql «1», и будет ждать окончания трафика на порту, как трафик закончился — отправит туда «2» и продолжит анализировать порт.

Денис

Добрый вечер, ковыряюсь в вышеуказанном коде. Понатыкал себе выводов для дебага, кое что причесал. Если от tcpdump нет вывода, нет трафика на порту, программа останавливается на process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) и ждет пока не появится какой либо вывод из tcpdump. Как это можно исправить, мне нужно как либо зафиксировать момент, когда трафик остановился и изменить переменную trig на 0.
#!/usr/bin/python3

import subprocess
import re
import time

def monitor_udp_traffic(port):
<——>trig=0
<——>while True:
<——><——>command = f»tcpdump -i any udp port {port}»
<——><——>print(«0»)
<——><——>process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
<——><——># Ждем, пока tcpdump начнет собирать данные
<——><——>print(«000»)
<——><——>time.sleep(1)
<——><——>try:
<——><——><——>while True:
<——><——><——># Считываем строки из вывода tcpdump
<——><——><——><——>print(«Reading»)
<——><——><——><——>line = process.stdout.readline().decode(«utf-8»)
<——><——><——><——>print(line)
<——><——><——><——>if not line:
<——><——><——><——><——>print(«10»)
<——><——><——><——><——>trig=0
<——><——><——><——><——>break
<——><——><——><——>#Проверяем, появился ли трафик на порту
<——><——><——><——>print(«4»)
<——><——><——><——>if re.search(f'{str(port)}: UDP’, line):
<——><——><——><——><——>trig=1
<——><——><——><——><——>print(«1»)
<——><——><——><——>else:
<——><——><——><——><——>print(«8»)
<——><——><——><——>print(trig)
<——><——>except KeyboardInterrupt:
<——><——><——># Обрабатываем прерывание с клавиатуры (Ctrl+C)
<——><——><——>process.terminate()
<——><——><——>break
if __name__ == «__main__»:
<——># Укажите номер UDP порта, который вы хотите мониторить
<——>udp_port = 4810
<——>monitor_udp_traffic(udp_port)

Читайте также

Спасибо!

Теперь редакторы в курсе.