В программировании мы часто выбираем самый простой инструмент, который решает задачу. Но простой выбор не всегда лучший, особенно если скрипту предстоит работать на разных компьютерах.
Проблема: Bash-скрипты не везде одинаково работают
Покажем на примере стандартного shell-скрипта, который:
Находит корневую папку проекта
Удаляет старые артефакты сборки
Обновляет файл версии
Запускает сборку
SCRIPT_PATH="$(readlink -f "$0")"
PROJECT_ROOT="$(dirname "${SCRIPT_PATH}")"
cd "${PROJECT_ROOT}"
find build gen -type f \( -name '*.o' -o -name '*.a' \) \
-print0 | xargs -0 -r rm
BUILD_DATE="$(date -d 'now' +%F)"
cp version.template build/version.txt
sed -i "s/@VERSION@/${COMMIT_TAG:-dev}/" build/version.txt
sed -i "s/@BUILD_DATE@/${BUILD_DATE}/" build/version.txtПроблема в том, что такой код работает на Linux, но может не работать на macOS, потому что:
Утилиты
readlink,find,xargs,date,sedведут себя по-разному или отсутствуютРазличия между GNU (Linux) и BSD (Mac) версиями инструментов приводят к ошибкам
Короче, что работает на вашем компьютере, может сломаться у коллеги или в CI/CD.
Было бы лучше использовать Python
Автор оригинальной статьи предлагает заменить сложные bash-скрипты на Python-скрипты. Почему?
1) Python есть почти везде
Python 3 сейчас установлен на большинстве систем, что означает, что ваши скрипты будут запускаться везде одинаково.
2) Многие разработчики уже знакомы с ним
Даже если вы не писали на Python в больших проектах, вы, скорее всего, уже видели его код или использовали простые скрипты, что снижает барьер вовлечения.
3) Большая стандартная библиотека
Python поставляется с обширной стандартной библиотекой, включающей всё, что нужно для скриптов:
работа с файлами,
JSON/XML,
сетевые запросы,
управление временем,
sqlite и др.
Это упрощает код и делает его кроссплатформенным без сторонних зависимостей.
4) Код проще читать
Автор отмечает, что Python-код легче понять и поддерживать, чем сложные конструкции Bash. Приводится сравнение трансформацию списка строк:
В Bash:
morning_greetings=('hi' 'hello' 'good morning')
energetic_morning_greetings=()
for s in "${morning_greetings[@]}"; do
energetic_morning_greetings+=( "${s^^}!" )
doneВ Python:
morning_greetings = ['hi', 'hello', 'good morning']
energetic_morning_greetings = [
s.upper() + '!' for s in morning_greetings
]Python-версия короче и понятнее даже тем, кто редко пишет такие вещи.
Когда это особенно важно
Это не значит, что обязательно нужно переписывать все простые скрипты в Python. Небольшие однострочные Bash-функции вполне нормальны. Но когда, скрипт становится длинным, логика сложная и скриптам нужна кросс-платформенность, то Python подойдет гораздо лучше.
Подведя итоги
Перейти от Bash к Python-скриптам стоит когда:
Вы хотите, чтобы код работал одинаково на разных системах
Легко читать и поддерживать чужие скрипты
Хотите воспользоваться мощной стандартной библиотекой
Скрипты становятся сложнее, чем "10 строк"