“Dry run” команд
Чтобы посмотреть, как будет выглядеть какая-то команда при выполнении - нужно просто написать перед командой echo, которая выведет команду, интерпретировав всякие переменные и т.д.:
Соус: Книга “Идиомы Bash” → Глава 2. Язык циклов → Разработка и тестирование циклов for
Эффективный перебор int значений
Если важна эффективность при переборе целочисленных значений - можно объявить переменную цикла как целочисленную:
Это позволит избежать ресурсоемких преобразований из строки в число и обратно.
Соус: Книга “Идиомы Bash” → Глава 2. Язык циклов → В заключение: стиль и удобочитаемость
Встроенные функции эффективнее команд
Юзать встроенные функции и ключевые слова эффективнее выполнения команд (которые исполняются во внешних файлах), особенно если зациклить их и вызывать много раз подряд.
Соус: Книга “Bash и кибербезопасность” → Глава 1. Работа с командной строкой → Основы работы с командной строкой → Команды, аргументы, встроенные функции и ключевые слова
Шаблоны - это не RegEx
Сопоставление c шаблоном в bash не является сопоставлением с регулярным выражением
В bash regex-ы поддерживаются только в операторе if
, если использовать оператор сравнения =~
.
Сопоставление с шаблоном или wildcarding в bash
Справки в скриптах
Не бойся добавлять даже большой справочный текст / справочные таблицы в конец скрипта. Функциональная часть будет находиться сверху, а справка снизу на случай, если пригодится. Одно другому не мешает.
Польза комментариев
Чтобы избежать недопонимания со стороны людей, незнакомых c bash, лучше дополнять первый (идиоматический) пример комментариями, объясняющими, что делает данный однострочник bash.
Да и вообще комменты в коде помогут читающему быстрее и легче понять этот код.
Команда help
Команда help
в bash дает краткие подсказки по встроенным функциям bash вместо объемного текста в man
.
KISS
Keep It Simple, Stupid.
Сложность - враг безопасности. Сложность затрудняет чтение, понимание, отладку. Понятно, что при современных требованиях системы не могу быть простыми, но делать сложнее, чем требуется, не нужно.
Цитата 🐺 от Brian Kernighan:
Отладка в 2 раза сложнее написания кода, поэтому написав настолько сложный код, насколько вы способны, по определению будете недостаточно умны, чтобы отладить его.
Don’t reinvent the wheel
Не изобретай велосипед: большинство задуманных тобой вещей уже было сделано раньше.
+ как бы ты не старался, превзойти качество и надежность, например, rsync
не сможешь - юзай его просто.
Пиши DRY код/документацию
Don’t Repeat Yourself.
Несколько копий одного и того же кода обязательно рассинхронизируются (чисто вопрос времени).
Проверка доступности внешних утилит
Проверяй их доступность так:
Соус: Книга “Идиомы Bash” → Глава 11. “Разработка своего руководства по стилю” → “Другие рекомендации”
Find out public IP
Создание временного файла с установкой ловушки для его удаления
Соус: Книга “Идиомы Bash” → Глава 7. “Списки и хеши” → “Пример подсчета слов” → “Пример 7.5”
Проверка, выполняется ли скрипт в интерактивном режиме
Иногда нужно знать, выполняется ли код в интерактивном режиме. Это может понадобится для изменения поведения при запросе ввода или для установки определенных конфиг-параметров интерактивной оболочки.
Также можно юзать проверку -t FD
, которая возвращает true, если дескриптор файлы открыт в терминале. Если дескриптор файла не указан, то возвращается 0
(STDIN
). Эту проверку можно объединить с другими тестами, например bash как оболочки:
В двух примерах выше были использованы одинарные кавычки вместо двойных, чтобы код мог выполняться другими интерпретаторами (например, dash).
Соус: Книга “Идиомы Bash” → Глава 9. “Файлы и не только” → “Код выполняется в интерактивном режиме?”
Локальные переменные
Если нужна локальная область видимости вне функции, юзай локальные переменные.
Как пример, возьму $IFS
, ибо обычно ее изменение нежелательно, поэтому целесообразнее изменять ее для определенного фрагмента кода (вне функции). In this case, нужно просто добавить присваивание переменной перед командой, для которой и требудется это изменение:
Соус: Книга “Идиомы Bash” → Глава 10. “Помимо идиом: работа с bash” → “Локальные переменные”
Поиск в списке процессов
При поиске процессов с помощью grep
одна из процессов - это сам grep
, а он мешается в выводе. Есть идиома, помогающая удалить строку с grep из вывода.
Вместо уродливого и неэффективного:
юзай идиому:
Строка
[p]roggy
в списке процессов не мэтчится с RegEx/[p]roggy/
, которое означаетproggy
. Короче,[p]roggy != proggy
.
Можно кстати еще юзать pgrep -fl
или старую команду pidof
.
Соус: Книга “Идиомы Bash” → Глава 10. “Помимо идиом: работа с bash” → “Поиск в списке процессов”
Ротация старых файлов
Логирование и архивирование логов круто, конечно, но иногда нужно сделать “ротацию” или удаление старых файлов.
Есть много идиоматических способов сделать это, здесь будут основные примеры.
Вот старые идиомы:
Идиома получше:
- Для теста юзай
-ls
или-print
вместо-delete
- Юзай
( )
для группировки (обрабатывать только те элементы, которые соответствуют всем критериям), но скобки нужно экранировать, чтобы избежать интерпретации командной оболочкой - Предполагается, что между параметрами в выражении используется оператор
-a
(and - и); но при необходимости можно также юзать-o
(or - или). Но лучше добавлять в код-a
, ибо явное лучше неявного.
Соус: Книга “Идиомы Bash” → Глава 10. “Помимо идиом: работа с bash” → “Ротация старых файлов”
Модульное тестирование в bash
Есть фреймворк модульного тестирования для bash скриптов (аналогичный фреймворкам JUnit, PyUnit и т.д.) → shunit2
Соус: Книга “Идиомы Bash” → Глава 10. “Помимо идиом: работа с bash” → “Модульное тестирование в bash”
Определение ОС
Примитивный пример определения операционной системы, на которой будет запущен этот код:
Соус: Книга Bash и кибербезопасность → Глава 2. Основы работы с bash → Написание первого сценари
я: определение типа операционной системы → Пример 2.3. osdetect.sh