После того, как я опубликовал предыдущую статью, в которой рассказал о том, какие приёмы применяю, создавая Shell-скрипты, отличающиеся отличным UX, сообщество Hacker News поделилось со мной ценными откликами и предложениями. Я оформил то, что мне удалось узнать, в виде новой статьи, разобрав здесь ещё шесть приёмов, которые позволят всем желающим улучшить свои скрипты.

1. Делайте свои скрипты пригодными для работы в различных окружениях и приспособленными для использования в конвейерах

Обращайте особое внимание на то, чтобы ваши скрипты хорошо работали бы в различных окружениях. Вот четыре основных приёма, которые позволяют этого добиться.

a) Используйте #!/usr/bin/env bash

Конструкция #!/usr/bin/env bash позволяет системе использовать переменную пользователя PATH для поиска исполняемого файла bash. Польза этого приёма очевидна, если принять во внимание то, что в разных системах оболочка bash может быть установлена в различных местах.

А вот конструкция #!/bin/bash непосредственно задаёт место, в котором нужно искать bash. В некоторых системах эта конструкция может оказаться неработоспособной.

b) Применяйте tput для организации переносимого цветового кодирования выходных данных скриптов

Вот пример:

if command -v tput &>/dev/null && [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then
    RED=$(tput setaf 1)
    GREEN=$(tput setaf 2)
    RESET=$(tput sgr0)
else
    RED=""
    GREEN=""
    RESET=""
fi

c) С уважением относитесь к переменной окружения $NO_COLOR

Как показано выше — перед использованием цветов проверьте переменную $NO_COLOR.

d) Выводите сообщения об ошибках в stderr

Пример:

echo "Error: Invalid input" >&2

2. Используйте printf вместо echo

Команда echo может, в различных условиях, вести себя не так, как ожидается, особенно — при установке определённых флагов или при выводе специальных символов. А вот команда printf в разных системах ведёт себя более предсказуемо:

printf "Hello, %s!\n" "$name"

3. Используйте shellcheck для поиска проблем в Shell-скриптах

ShellCheck — это потрясающий инструмент, который позволяет выявлять в Shell-скриптах распространённые проблемы. Например — он обратил моё внимание на следующую конструкцию, способную превратиться в проблему, когда анализировал мой скрипт evaluate.sh:

# До
rm -rf $dir/*

# После (Предложение ShellCheck)
rm -rf "$dir"/*

Всегда прогоняйте свои скрипты через ShellCheck перед тем, как сочтёте их готовыми к работе.

4. Помните о разнице между двойными и одинарными квадратными скобками

Двойные скобки — [[]] — это расширение bash, которое даёт больше возможностей, чем одинарные скобки — []. Их применение обычно позволяет сделать код безопаснее и гибче. Вот основные отличия разных конструкций из квадратных скобок:

# Сопоставление с шаблоном при использовании одинарных скобок не работает
file="my-special-file.txt"
if [ "$file" = *.txt ]; then    # Всегда  false! Выполняется строковое сравнение
    echo "Single brackets don't do pattern matching"
fi

if [[ $file == *.txt ]]; then   # Работает! Выполняется сопоставление с шаблоном
    echo "Double brackets support pattern matching"
fi

# Различается поведение при разделении слов
path="/some path/with spaces"
if [ -d "$path" ]; then         # Переменную нужно заключать в кавычки
    echo "Single brackets need quotes"
fi

if [[ -d $path ]]; then         # Кавычки необязательно (но рекомендованы)
    echo "Double brackets handle spaces"
fi

# Логические операторы ведут себя по-разному
if [ "$a" = "1" ] && [ "$b" = "2" ]; then     # Нужны операторы оболочки
    echo "Single brackets use shell && ||"
fi

if [[ $a == 1 && $b == 2 ]]; then             # Можно использовать встроенные операторы
    echo "Double brackets have logical operators"
fi

# Регулярные выражения работают лишь в двойных скобках
if [[ $number =~ ^[0-9]+$ ]]; then            # Поддержка регулярных выражений
    echo "Double brackets support regex with =~"
fi

Двойные скобки прощают больше оплошностей и обладают более широкими возможностями, чем одинарные. Но они работают только в оболочке bash. Если вам нужно, чтобы ваши скрипты были бы POSIX-совместимыми (чтобы они работали в других оболочках — вроде dash или sh) — используйте одинарные скобки. А в остальных случаях двойные скобки обычно удобнее и позволяют писать более безопасный код.

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

5. При возникновении ошибок, связанных с неправильным использованием команд, применяйте команду exit 2 вместо команды exit 1

Общепринятым является подход, когда, если возникают синтаксические ошибки при использовании командной строки, применяется код выхода 2:

if [ $# -eq 0 ]; then
    echo "Usage: $0 <argument>" >&2
    exit 2
fi

6. Используйте шаблоны bash-скриптов

Шаблоны bash-скриптов могут помочь в создании надёжной базы для ваших собственных разработок. Один из популярных вариантов таких шаблонов — bash3boilerplate. Вот — простой пример:

#!/usr/bin/env bash

set -o errexit
set -o pipefail
set -o nounset

__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"

arg1="${1:-}"

# Тут будет ваш код

Итоги

Если вам было интересно узнать об этих приёмах — можете почитать мою предыдущую статью. Там подняты следующие темы:

  1. Всеобъемлющая обработка ошибок и проверка входных данных

  2. Понятные выходные данные, оформляемые с использованием разных цветов

  3. Подробные сведения о ходе работы скрипта

  4. Стратегический подход к обработке ошибок с помощью set -e и set +e

  5. Адаптация скрипта к различным платформам

  6. Использование временных меток при сохранении в файлах результатов множества вызовов скрипта

Кроме того — можете заглянуть на страницу Hacker News с обсуждением той статьи, которое вдохновило меня на написание этого материала.

Благодарю сообщество Hacker News за ценные советы. Удачи всем в написании скриптов!

О, а приходите к нам работать? ? ?

Мы в wunderfund.io занимаемся высокочастотной алготорговлей с 2014 года. Высокочастотная торговля — это непрерывное соревнование лучших программистов и математиков всего мира. Присоединившись к нам, вы станете частью этой увлекательной схватки.

Мы предлагаем интересные и сложные задачи по анализу данных и low latency разработке для увлеченных исследователей и программистов. Гибкий график и никакой бюрократии, решения быстро принимаются и воплощаются в жизнь.

Сейчас мы ищем плюсовиков, питонистов, дата-инженеров и мл-рисерчеров.

Присоединяйтесь к нашей команде

Комментарии (1)


  1. amarkevich
    04.08.2025 10:56

    в контейнерах часто отсутствует bash, поэтому лучше по возможности делать скрипты на sh