Написание консольных скриптов: Bash против Python

Компьютер  —  это цифровое устройство, распознающее только определенные двоичные инструкции. Без операционной системы можно пользоваться лишь некоторым количеством встроенных на аппаратном уровне микропрограмм, таких как утилиты BIOS.

Операционные системы упрощают работу с компьютерами и позволяют запускать предварительно разработанные программы (например, текстовые процессоры, веб-браузеры и утилиты). Сегодня большинство операционных систем работают как с графическим интерфейсом пользователя (GUI, Graphical User Interface), так и с интерфейсом командной строки (CLI, Command Line Interface).

Программисты обычно выбирают интерфейс командной строки, поскольку по сравнению с графическим интерфейсом он лучше подходит для их повседневных дел. Через CLI часто развертывают ПО, работают с файловой системой и настраивают компьютер. CLI  —  это эффективный способ выполнять разные задачи. Но при этом часто одни и те же вводимые команды приходится запускать с некоторыми изменениями.

В результате появились интерпретаторы CLI и концепция сценариев (англ. shell script) для запуска файлов с предварительно написанными командами. Bash  —  это популярный командный язык для запуска сценариев, который встроен в большинство операционных систем. С другой стороны, многие программисты используют в качестве альтернативы Python, имеющий встроенные функции, которых нет у Bash.

Сравним Bash и Python с точки зрения написания консольных сценариев. Помимо этого, разберем менее известные методы написания таких сценариев, позволяющие улучшить навыки автоматизации с помощью Bash и Python.


Bash: самый естественный способ писать консольные скрипты

Основным предназначением сценариев командной оболочки является запуск и выполнение с помощью интерпретатора предварительно написанной последовательности команд. Обрабатывая каждый ввод/выражение как команду, Bash обеспечивает эффективную автоматизацию повседневных рутинных операций. Вспомните, как вы впервые использовали терминал на базе Bash, не читая документации и не следуя учебнику:

Первый опыт работы с Bash в текстовом окне

Bash не работает как язык общего назначения  —  он всегда мотивирует использовать другие программы. Например, для приведенного выше сценария можно использовать expr 10 + 15. Однако сегодня Bash поддерживает еще и встроенные функции для решения распространенных задач, поэтому другие программы вызывать нужно не всегда.

Например, основные арифметические операции позволяет выполнять функция арифметических расширений:

Использование функции арифметического расширения

Bash выполняет команды нативно, без специального расширенного синтаксиса. Для стандартных задач программирования этого достаточно.


Python: современный способ расширения функциональности Bash

Если Bash нативно выполняет стандартные команды и поддерживает многие популярные функции, то почему программисты используют для автоматизации своих операций Python? Ответ в следующей выдержке из документации Python самых ранних выпусков:

Ранняя версия документации Python

Согласно этой документации, Python изначально разрабатывался для объединения языка сценариев оболочки и возможностей программирования на уровне операционной системы. Bash не имеет нативного доступа к API уровня операционной системы (известным как C API).

Таким образом, если сценарию требовался доступ к C API, приходилось использовать такие обходные пути, как создание исполняемого файла на другом языке программирования. Python решил эту проблему: он предложил удобный для автоматизации лаконичный язык с доступом к C API и даже с кросс-платформенным доступом к API уровня операционной системы.

Python оценивает исходный код с точки зрения операций стандартного программирования  —  сам по себе он не может выполнять другие программы, но предлагает API дочерних процессов (child process API).

Выяснив как цели, так и основы Bash и Python, займемся теперь их сравнением.


Bash или Python: что лучше для автоматизации

Программисты пишут различные сценарии оболочки, в том числе выполняющие несколько команд POSIX (например, mv, cp и т. д.). В некоторых случаях необходимо включить в них обработку данных и операции на уровне ОС. А иногда нужно писать и кроссплатформенные скрипты автоматизации.

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

Bash хорош для следующих сценариев.

  • Автоматизация операций командной строки POSIX с небольшим объемом обрабатываемых данных, т. е. сценариев системного администрирования.
  • Написание сценариев оболочки, которые выполняют настройку, обработку и другие операции с помощью программ CLI. Например, написание сообщений фиксации Git и развертывание приложения с помощью инструментария CLI.
  • Bash  —  хороший вариант для сценариев в Unix с расширенной переносимостью, поскольку интерпретатор Bash более широко предустановлен, чем Python.

Python хорош для следующих сценариев.

  • Автоматизация задач, включающих больше обработки данных (алгоритмических операций) и доступа к низкоуровневым API, чем выполнения других программ CLI.
  • Написание кроссплатформенных сценариев автоматизации, которые выполняют команды, используют низкоуровневые API и выполняют общую обработку данных в GNU/Linux, Windows, macOS и других ОС с поддержкой Python. Например, исходный код BuildZri.

В целом, Bash  —  это самый минимальный, естественный и нативный способ написания сценариев автоматизации с другими программами командной строки в текстовом окне. С другой стороны, Python  —  это стандартный кроссплатформенный язык. Его можно использовать в качестве альтернативы Bash для написания сценариев оболочки с доступом к низкоуровневым API операционной системы и обработкой данных.


Используйте Bash и Python совместно

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

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

#!/bin/bash

sum=$(bc <<< "1.5 + 2.51")
echo $sum

С помощью Python можно сделать то же самое:

#!/bin/bash

sum=$(python3 <<< "print(1.5 + 2.51)")
echo $sum

Многие программисты используют Bash в своих сценариях Python. Это удобнее, чем применять разные сторонние пакеты Python. Например, следующий скрипт находит идентификатор процесса программы Gedit:

#!/usr/bin/env python3


import subprocess

gedit_pid = subprocess \
.getoutput("ps -ef | grep gedit | head -1 | awk '{print $2}'") \
.strip()
print(gedit_pid)

Решение проблем Bash и Python

И у Bash, и у Python есть некоторые недостатки применительно к современным требованиям к автоматизации. С Bash довольно трудно писать сценарии оболочки с доступом к API на уровне операционной системы и выполнять обработку сложных данных. В Python с API subprocess написание минимально исполняемых программ из командной строки синтаксически не похоже на оболочку.

Для C API в Bash имеется расширение Bash ctypes.sh..

Есть даже веб-сервер HTTP httpd.sh, написанный на Bash с использованием интерфейса внешних функций (FFI) ctypes.sh.

Проект pysh предлагает простой способ выполнения операторов Bash в скриптах Python с помощью символа >, как показано в следующем фрагменте кода:

for i in xrange(100):
index = "%02d" % i
> mv from$index.txt to$index.txt

Проект zxpy (на основе zx от Google) позволяет продуктивно выполнять операции командной строки с помощью Python следующим образом:

#! /usr/bin/env zxpy
~'echo Hello world!'

file_count = ~'ls -1 | wc -l'
print("file count is:", file_count)

Заключение

Концепция сценариев оболочки появилась в 1970-х годах вместе с оболочкой Thompson для среды Unix. Идея традиционных сценариев оболочки заключается в выполнении операций командной строки из файла в целях автоматизации. Современная методология DevOps расширила традиционную концепцию сценариев оболочки для автоматизации, включив в нее вызовы RESTful API, обработку данных и другие операции DevOps.

Использовать Bash для создания сценариев оболочки не считается устаревшей практикой, поскольку так можно выполнять команды в исходном формате без API дочерних процессов (они включены нативно). Python часто используют как современную альтернативу Bash, расширяющую его нативные возможности операций командной строки.

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

Читайте нас в TelegramVK и Дзен


Перевод статьи Shalitha Suranga: Bash vs. Python: For Modern Shell Scripting

Предыдущая статьяТоп-10 библиотек React для создания высокопроизводительных веб-приложений в 2023 году
Следующая статьяКэширование Redis для максимальной производительности в Spring Boot и Java