bash скрипты для начинающих — урок №13: Ключи.

Предыдущий урок: bash скрипты для начинающих — урок №12: Оператор case.

На прошлых уроках мы изучили использование аргументов для передачи значений в скрипт, а так же рассмотрели использование case для управления выбором. Сегодня мы продолжим изучать основы  управления скриптом.

Зачем нужны ключи?

Настройка режима работы: Ключи позволяют запускать команду или скрипт в различных режимах или с разными параметрами, не меняя сам код.

Повышение читаемости и удобства: Использование ключей делает команду более понятной и логичной, так как явно обозначает, что именно делается.

Обеспечение универсальности и расширяемости: Можно добавлять новые ключи без изменения основной логики скрипта. Каждая опция — это способ включить или отключить определенное поведение.

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

Ключи

Подготовим новый файл для урока:

[root@waky bash_practice]# touch script_13.sh
[root@waky bash_practice]# chmod +x script_13.sh
[root@waky bash_practice]#

Шаг 1: Пишем скрипт с ключами

Запишем в script_13.sh следующий код:

#!/bin/bash

error_log_file=./script_13.error_log

log_errors() {
    local log_file=$1
    local error_message=$2
    local timestamp=$(date +%d/%m/%Y-%H:%M:%S)

    echo "$timestamp: $error_message" >> $log_file
}

count_files_in_directory() {
    local directory=$1
    files_in_dir=$( ls $directory )
    if [ $? -ne 0 ]; then
        if [ "$err_log_enabled" == "true" ]; then
            log_errors $error_log_file "ERROR: Failed to count files in $directory."
        fi
    else
        files_count=$( echo $files_in_dir | wc -w )
        echo "There are $files_count files in $directory directory."
    fi
}

VALID_ARGS=$(getopt -o t:e: --long target:,errlog: -- "$@")
if [ $? -ne 0 ]; then
    echo "Wrong keys were used"
    exit 1
fi
eval set -- "$VALID_ARGS"
while [ : ];
do
    case "$1" in
        -t | --target)
            target=$2
            shift 2;;
        -e | --errlog)
            err_log_enabled=$2
            shift 2;;
        *)
            break;;
    esac
done

count_files_in_directory $target

В нашем скрипте две функции log_errors, для логирования в случае возникновения ошибок, и count_files_in_directory для подсчета файлов в указанной директории.

С помощью getopt мы указываем короткие и длинные имена ключей, которые можно задать. В нашем случае ключей всего два t (—target) и e (—errlog). Первый ключ указывает директорию, с которой будет работать скрипт, второй — включает логирование.

Принятые ключи записываются в VALID_ARGS и обрабатываются с помощью eval set, чтобы отделить их друг от друга. Затем с помощью цикла while мы перебираем пары ключ/значение и записываем значения в соответствующие переменные.

После определения ключей и значений, запускаем функцию count_files_in_directory нацеленную на директорию, переданную в target.

Шаг 2: Проверяем работу скрипта

Проверим, как работает наш скрипт:

[root@waky bash_practice]# ./script_13.sh -t ./
There are 16 files in ./ directory.
[root@waky bash_practice]#

Попробуем задать несуществующую директорию:

[root@waky bash_practice]# ./script_13.sh -t /not_exist
ls: cannot access '/not_exist': No such file or directory
[root@waky bash_practice]#

Ожидаемо посчитать файлы в несуществующей директории не удалось. Проверим создался ли файл логов (script_13.error_log):

[root@waky bash_practice]# cat script_13.error_log
cat: script_13.error_log: No such file or directory
[root@waky bash_practice]#

Файл отсутствует, так как скрипт был запущен без ключа, включающего логирование. Повторим попытку с этим ключом:

[root@waky bash_practice]# ./script_13.sh -t /not_exist -e true
ls: cannot access '/not_exist': No such file or directory
[root@waky bash_practice]#

Проверим файл логов:

[root@waky bash_practice]# cat script_13.error_log
27/12/2025-04:42:16: ERROR: Failed to count files in /not_exist.
[root@waky bash_practice]#

Отлично, с включенными логами файл был создан и записан.

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

Запустим скрипт еще раз, поменяв местами ключи:

[root@waky bash_practice]# ./script_13.sh -e true -t /not_exist
ls: cannot access '/not_exist': No such file or directory
[root@waky bash_practice]# ./script_13.sh -e true -t ./
There are 17 files in ./ directory.
[root@waky bash_practice]# cat script_13.error_log
27/12/2025-04:42:16: ERROR: Failed to count files in /not_exist.
27/12/2025-04:46:27: ERROR: Failed to count files in /not_exist.
[root@waky bash_practice]#

Скрипт одинаково работает вне зависимости от положения ключей.

Итоги:

Сегодня мы научились задавать ключи для нашего скрипта. К тому же в процессе мы вспомнили многие элементы из предыдущих уроков. Вся мощь bash скриптов раскрывается при умелом совмещении всех базовых элементов.

Следующий урок: bash скрипты для начинающих — урок №14: Usage и комментарии.