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

Предыдущий урок: bash скрипты для начинающих — урок №4: Использование if else условий.

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

Зачем нужны коды выхода?

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

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

Передача состояния выполнения: Другие программы или скрипты могут проверять код выхода и принимать решения: например, повторить попытку или остановить выполнение.

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

Автоматизация и условные конструкции: Можно писать условия типа if [ $? -eq 0 ], чтобы выполнить определённые команды только в случае успешного завершения предыдущих.

Коды выхода

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

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

Шаг 1: Проверяем коды выхода

Заполним файл script_5.sh следующим содержанием:

#!/bin/bash

exist_file="./script_5.sh"
not_exist_file="./not_exist.txt"

ls $exist_file
echo "exit code 1: $?"

ls $not_exist_file
echo "exit code 2: $?"

ls $exist_file
ls $not_exist_file
echo "exit code 3: $?"

ls $not_exist_file
if [ $? == "0" ]; then
    echo "exit code 4: $?"
    echo "file already exists"
else
    echo "exit code 4: $?"
    echo "no such file, creating file"
    touch $not_exist_file
fi 

Запустим скрипт и проанализируем полученный результат:

[root@waky bash_practice]# ./script_5.sh
./script_5.sh
exit code 1: 0
ls: cannot access './not_exist.txt': No such file or directory
exit code 2: 2
./script_5.sh
ls: cannot access './not_exist.txt': No such file or directory
exit code 3: 2
ls: cannot access './not_exist.txt': No such file or directory
exit code 4: 1
no such file, creating file
[root@waky bash_practice]#

Первый код — 0, проверяемый файл на месте, код выхода успешный. Второй код напротив, файл отсутствует, код не нулевой. Третий код снова не нулевой, хотя первая команда отработала штатно, $? содержит код выхода последней команды, которая в нашем случае закончилась неудачей.

Код выхода широко используется с конструкцией if. В нашем случае, в зависимости от успешного и неуспешного выполнения предыдущей команды, с помощью if мы выбираем следующее действие. В частности, мы создаем отсутствующий файл.

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

[root@waky bash_practice]# ./script_5.sh
./script_5.sh
exit code 1: 0
./not_exist.txt
exit code 2: 0
./script_5.sh
./not_exist.txt
exit code 3: 0
./not_exist.txt
exit code 4: 0
file already exists
[root@waky bash_practice]#

Теперь, не смотря на название, файл not_exist.txt существует, как результат все команды в скрипте выполнены успешно, коды выхода везде 0.

Шаг 2: Задаем коды выхода

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

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

#!/bin/bash

number_of_errors=3

if [ $number_of_errors -eq 0 ]; then
    echo "No errors"
    exit 0
elif [ $number_of_errors -lt 5 ]; then
    echo "Some errors"
    exit 1
else
    echo "A lot of errors"
    exit 2
fi

Запустим скрипт:

[root@waky bash_practice]# ./script_5.sh
Some errors
[root@waky bash_practice]#

Сразу после этого проверим код выхода скрипта:

[root@waky bash_practice]# echo $?
1
[root@waky bash_practice]#

Изменим переменную number_of_errors в скрипте с 3 на 10, и повторим проверку:

[root@waky bash_practice]# ./script_5.sh
A lot of errors
[root@waky bash_practice]# echo $?
2
[root@waky bash_practice]#

В зависимости от соответствия условиям скрипт возвращает разный код выхода.

Итоги:

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

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