Три настройки оболочки останавливают скрипт на сбое, который ты не проверил сам. Их пишут второй строкой скрипта: set -euo pipefail.
set -e завершает скрипт на первой команде со сбоем, и код скрипта — код этой команды. Сбой внутри условия — после if, слева от && или || — скрипт не останавливает: этот код ты проверяешь сам. Поэтому FAIL печатает только явная проверка: с одним set -e скрипт с curl к лежащему приложению молча завершится кодом 7.
set -u делает ошибкой обращение к переменной, которой нет. Опечатка $URl вместо $URL без этой настройки даёт пустую строку, с ней — сообщение URl: unbound variable и остановку скрипта.
Код конвейера — код его последней команды. В curl -sf … | tee -a health.log это код tee: она записала пустой вывод и завершилась успехом, хотя curl упал. С set -o pipefail код конвейера — код последней упавшей в нём команды.
Файла app.log в каталоге нет. Что напечатает ./report.sh?
#!/bin/bash
set -e
grep ERROR app.log | wc -l
echo "report done"
-
Код конвейера — код последней команды, wc: она сосчитала ноль строк и завершилась успехом. Остановит скрипт только
set -o pipefail. -
grep пишет
No such file or directoryв поток ошибок, мимо конвейера, — сообщение на экране тоже есть.
grep упал, но код конвейера дала wc — ноль, и set -e скрипт не остановил. Сбой grep сделает кодом конвейера set -o pipefail.
Главное в шаге
-
set -eостанавливает скрипт на первом непроверенном сбое; сбой послеif, слева от&&и||его не останавливает. -
set -uпревращает опечатку в имени переменной в ошибку вместо пустой строки. -
С
pipefailсбой в начале конвейера не прячется за успехом его последней команды.