Поиск по сайту:
Вера вопрошает, разум обнаруживает (Августин).

Выполнение команд оболочки с 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 Звезд (2 оценок, среднее: 5,00 из 5)
Загрузка...
Поделиться в соц. сетях:

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

  1. kadyr:

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

  2. Денис:

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

    • Примерно так:

      import subprocess
      import re
      import time

      def monitor_udp_traffic(port):
      while True:
      # Запускаем tcpdump с указанием порта
      command = f”tcpdump -i any udp port {port}”
      process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

      # Ждем, пока tcpdump начнет собирать данные
      time.sleep(2)

      try:
      while True:
      # Считываем строки из вывода tcpdump
      line = process.stdout.readline().decode(‘utf-8’)

      if not line:
      break

      # Проверяем, появился ли трафик на порту
      if re.search(f”UDP.*:{port}”, line):
      print(“1”)

      except KeyboardInterrupt:
      # Обрабатываем прерывание с клавиатуры (Ctrl+C)
      process.terminate()
      break

      if __name__ == “__main__”:
      # Укажите номер UDP порта, который вы хотите мониторить
      udp_port = 12345
      monitor_udp_traffic(udp_port)

      • Денис:

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

        • так доработайте, основу так то дали, примерно так:

          if (…) :
          print(‘1’)
          else:
          print(‘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)


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

девятнадцать − девятнадцать =

**ссылки nofollow

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

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: