При написании скриптов важно не просто запускать команды, но и гарантировать их корректное выполнение. Без дополнительных опций Bash может пропустить ошибки и продолжить выполнение, что приведёт к неожиданным последствиям. Использование
set -euo pipefail помогает защитить скрипты от ошибок и упростить отладку.❓ Что делает эта магическая строка?
set -euo pipefail
-e (exit on error) — прерывает скрипт при ошибке любой команды (кроме в if, &&, ||).
-u (unset variables) — ошибка при попытке использовать неинициализированную переменную.
-o pipefail — ошибка в пайпах, если любая из команд завершится с ошибкой (обычно учитывается только последняя команда).
Разберём на примерах.
🚫 Скрипт без set -euo pipefail (пропустит ошибки)
#!/bin/bash
echo "Начинаем работу..."
rm /несуществующий_файл # Ошибка, но скрипт продолжит работу
echo "Удалили файл (на самом деле нет)"
VAR=$(cat $UNKNOWN_VAR) # Неинициализированная переменная (ошибка, но не критично)
ls | grep myfile | awk '{print $1}' # Ошибка в grep или awk не остановит выполнение
echo "Скрипт завершён"
Итог: скрипт продолжает работать, даже если что-то пошло не так.
✔️ Скрипт с set -euo pipefail (контроль ошибок)
#!/bin/bash
set -euo pipefail
echo "Начинаем работу..."
rm /несуществующий_файл # Скрипт сразу прервётся из-за ошибки
echo "Удалили файл"
VAR=$(cat $UNKNOWN_VAR) # Ошибка: переменная не объявлена
ls | grep myfile | awk '{print $1}' # Ошибка в любой команде пайпа приведёт к остановке
echo "Скрипт завершён"
Итог: скрипт остановится сразу при первой же ошибке, не допуская некорректного выполнения.
⭐️ Где это особенно полезно?
Бэкап-скрипты (чтобы не создать пустой бэкап, если команда провалилась).
Скрипты развёртывания (чтобы не получить систему в непредсказуемом состоянии).
Автоматизация обновлений (чтобы обновление не зависло в неизвестном месте).
❗️ Когда set -euo pipefail может мешать? Иногда ошибки могут быть ожидаемыми и не критичными.
Например, если файл может отсутствовать, но это не должно останавливать выполнение:
rm myfile.txt || true # Явно игнорируем ошибку
Или если команда в пайпе не всегда должна возвращать код 0:
set +o pipefail # Отключаем pipefail временно
ls | grep myfile | awk '{print $1}'
set -o pipefail # Включаем обратно
BashTex 📱 #linux #utils