Як запускати сценарії bash за допомогою Python?

Якщо ви використовуєте Linux, то вам точно сподобаються команди оболонки.

І якщо ви працюєте з Python, можливо, ви намагалися автоматизувати речі. Це спосіб заощадити час. Ви також можете мати сценарії bash для автоматизації.

Python зручний для написання сценаріїв, ніж bash. А керувати сценаріями Python легко порівняно зі сценаріями bash. Вам буде важко підтримувати сценарії bash, коли він зростатиме.

Але що, якщо у вас уже є сценарії bash, які ви хочете запустити за допомогою Python?

Чи є спосіб виконати команди та сценарії bash у Python?

Так, Python має вбудований модуль під назвою subprocess, який використовується для виконання команд і сценаріїв у сценаріях Python. Давайте детально розглянемо, як виконувати команди та сценарії bash у сценаріях Python.

Виконання команд Bash

Як ви вже могли бачити, підпроцес модуля використовується для виконання команд і сценаріїв bash. Він надає різні методи та класи для того самого.

Є в основному один метод і один клас, про які слід знати з модуля підпроцесу. Вони запускаються і Попен. Ці два допомагають нам виконувати команди bash у сценаріях Python. Давайте розглянемо їх по одному.

subprocess.run()

Метод subprocess.run() прийматиме список рядків як позиційний аргумент. Це обов’язково, оскільки містить команду bash і аргументи для неї. Перший елемент у списку – це ім’я команди, а решта – аргументи команди.

Давайте розглянемо короткий приклад.

import subprocess
subprocess.run(["ls"])

Наведений вище сценарій перераховує всі елементи в поточному робочому каталозі, як сценарій лежить. У наведеному вище сценарії немає аргументів для команди. Ми дали лише команду bash. Ми можемо надати додаткові аргументи команді ls, наприклад -l, -a, -la тощо.

  Чому мій iPhone не заряджається?

Давайте розглянемо короткий приклад з аргументами команди.

import subprocess
subprocess.run(["ls", "-la"])

Наведена вище команда відображає всі файли, включаючи приховані, разом із дозволами. Ми надали аргумент la, який відображає файли та каталоги, додаткову інформацію та приховані файли.

Під час написання команд ми можемо зробити деякі помилки. Помилки будуть зростати відповідно до помилок. Що робити, якщо ви хочете захопити їх і використати пізніше? Так, ми можемо зробити це за допомогою ключового аргументу stderr.

Давайте розглянемо приклад.

import subprocess
result = subprocess.run(["cat", "sample.txt"], stderr=subprocess.PIPE, text=True)
print(result.stderr)

Переконайтеся, що у вас немає файлу з назвою sample.txt у робочому каталозі. Значенням ключового аргументу stderr є PIPE, яке допомагає повернути помилку в об’єкті. Пізніше ми зможемо отримати доступ до нього з тим самим іменем. А текст аргументу ключового слова допомагає зрозуміти, що результат має бути рядком.

Подібним чином ми можемо отримати вихід команди за допомогою аргументу ключового слова stdout.

import subprocess
result = subprocess.run(["echo", "Hello, World!"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print(result.stdout)

subprocess.run() – вхід

Ви можете вводити команди за допомогою ключового аргументу input. Ми надамо вхідні дані у форматі рядка. Отже, нам потрібно встановити для тексту аргументу ключового слова значення True. За замовчуванням він приймає його в байтах.

Давайте розглянемо приклад.

import subprocess
subprocess.run(["python3", "add.py"], text=True, input="2 3")

У наведеній вище програмі сценарій Python add.py прийматиме два числа як вхідні дані. Ми надали вхідні дані сценарію Python за допомогою аргументу ключового слова input.

  Хочете створити стартап Femtech? Ось як

subprocess.Popen()

Клас subprocess.Popen() є розширенішим, ніж метод subprocess.run(). Це дає нам більше можливостей для виконання команд. Ми створимо екземпляр subprocess.Popen() і використовуватимемо його для різних речей, як-от знання статусу виконання команди, отримання виводу, введення даних тощо.

Існує кілька методів класу subprocess.Popen(), які нам потрібно знати. Давайте розглянемо їх один за одним разом із прикладами коду.

чекати

Використовується для очікування завершення виконання команди. Наступні рядки сценарію Python не виконуватимуться до завершення попередньої команди, написаної після методу wait. Давайте подивимося на прикладі.

import subprocess
process = subprocess.Popen(["ls", "-la"])
print("Completed!")

Запустіть наведений вище код і спостерігайте за результатом. Ви побачите, що повідомлення Виконано! друкується перед виконанням команди. Ми можемо уникнути цього за допомогою методу очікування. Дочекаємося завершення виконання команди.

import subprocess
process = subprocess.Popen(["ls", "-la"])
process.wait()

print("Completed!")

Якщо ви побачите вихід для наведеного вище коду, ви зрозумієте, що очікування насправді працює. Оператор друку виконується після завершення виконання команди.

спілкуватися

Метод communicate використовується для отримання виводу, помилки та введення в команду. Він повертає кортеж, що містить результат і помилку відповідно. Давайте розглянемо приклад.

import subprocess
process = subprocess.Popen(["echo", "Hello, World!"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
result = process.communicate()
print(result)

subprocess.Popen() – вхід

Ми не можемо передати вхідні дані класу Popen безпосередньо. Нам потрібно використати ключовий аргумент під назвою stdin, щоб надати вхідні дані команді. Екземпляр класу Popen надасть нам об’єкт stdin. Він має метод під назвою write, який використовується для введення команди.

Як ми обговорювали раніше, він прийматиме вхідні дані як байтоподібні об’єкти за замовчуванням. Отже, не забудьте встановити для тексту аргументу ключового слова значення True під час створення екземпляра Popen.

  Що таке серйозні помилки в секунду? Як це виправити

Давайте розглянемо приклад.

import subprocess
process = subprocess.Popen(["python3", "add.py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
process.stdin.write("2 3")
process.stdin.close()
print(process.stdout.read())

опитування

Опитування методу використовується для перевірки того, завершено чи ні завершено виконання команди. Цей метод поверне None, якщо команда все ще виконується. Давайте розглянемо приклад.

import subprocess
process = subprocess.Popen(['ping', '-c 5', 'geekflare.com'], stdout=subprocess.PIPE, text=True)
while True:
    output = process.stdout.readline()
    if output:
    	print(output.strip())
    result = process.poll()
    if result is not None:
        break

У наведеному вище коді ми використали команду ping із 5 запитами. Існує нескінченний цикл, який повторюється до завершення виконання команди. Ми використали метод poll для перевірки статусу виконання команди. Якщо опитування методу повертає код, відмінний від None, тоді виконання завершується. І нескінченна петля розривається.

Виконання сценаріїв Bash

Ми бачили два способи виконання команд. Тепер давайте подивимося, як виконувати сценарії bash у сценаріях Python.

Підпроцес має метод під назвою call. Цей метод використовується для виконання сценаріїв bash. Метод повертає код виходу зі сценарію bash. Стандартним кодом виходу для сценаріїв bash є 0. Давайте подивимося на приклад.

Створіть сценарій bash з іменем practice.sh наступним чином.

#!/bin/bash

echo "Hello, World!"
exit 1

Тепер напишіть сценарій Python, виконайте наведений вище сценарій bash.

import subprocess
exit_code = subprocess.call('./practice.sh')
print(exit_code)

Ви отримаєте наступні результати, коли запустите наведений вище сценарій Python.

Hello, World!
1

Висновок

Ми побачили, як виконувати команди і сценарії bash у Python. Ви можете використовувати їх для ефективнішої автоматизації.

Щасливого кодування 👨‍💻