linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Процессы и ресурсы/bash-strict-mode

kb/processes ── Процессы и ресурсы ── intermediate

Bash strict mode: set -euo pipefail

Три флага в начале bash-скрипта которые превращают его из «прощающего всё» в «упасть на первой же ошибке». Без них баги молча копятся.

view as markdownaka: strict-mode, set-e, set-u, pipefail, errexit, nounset

Зачем нужно

По умолчанию bash не падает при ошибках - продолжает выполнять скрипт дальше, как ни в чём не бывало:

bash
#!/usr/bin/env bash
cp /no/such/file /tmp/dest   

▸ошибка, но скрипт идёт дальше

rm -rf /tmp/dest/*            

▸теперь это удалит ЧТО-ТО ДРУГОЕ

Без strict mode такой скрипт молча крашит данные. Strict mode = три флага которые обязаны стоять в начале любого нетривиального скрипта:

bash
set -euo pipefail

Что делает каждый флаг

ФлагLong nameЭффект
-eerrexitУпасть сразу на первой команде с exit-code != 0
-unounsetУпасть если используешь не установленную переменную
-o pipefailpipefailPipe считается упавшим если любое звено упало

Без pipefail команда cmd1 | cmd2 имеет exit-code от последней команды в пайпе. То есть false | true вернёт 0 (успех) - потому что bash смотрит только на true. С pipefail - увидит что false упал и pipe тоже упадёт.

Идиома

Стандартная прелюдия каждого production-скрипта:

bash
#!/usr/bin/env bash
set -euo pipefail
# дальше твой код

Иногда добавляют -x для отладки (трассировка каждой команды в stderr):

bash
set -euxo pipefail   # с трассировкой

Или включают временно:

bash
set -x
some_buggy_command
set +x   # выключить

Когда нужно отключить локально

Иногда -e мешает: команда специально может вернуть != 0, и это OK. Тогда - || true или явная проверка:

bash
# diff возвращает 1 если файлы различаются - для нас это не ошибка
diff a.txt b.txt > result.txt || true
# Альтернатива - вырубить -e на одну команду
if some_check; then
    echo ok
else
    echo "check failed but we're fine with that"
fi

С -u похожая ловушка: ${VAR:-default} даёт значение по умолчанию если переменная не установлена, без падения:

bash
PORT=${PORT:-8080}    # 8080 если PORT не задан
echo "${OPTIONAL:-}"  # пустая строка вместо ошибки

Альтернативы и нюансы

  • set -E - ловушки trap ERR наследуются в функциях (по умолчанию нет)
  • set -o functrace - то же для DEBUG/RETURN traps
  • shopt -s inherit_errexit - -e наследуется в command-substitution $(...) (тоже не работает по умолчанию!)

Полная защитная прелюдия которую видно в проде:

bash
#!/usr/bin/env bash
set -Eeuo pipefail
shopt -s inherit_errexit   # bash 4.4+
trap 'echo "ERROR at line $LINENO" >&2' ERR

§ команды

bash
set -euo pipefail

Стандартная защитная прелюдия - обязательна в начале любого скрипта

bash
set -x

Включить трассировку: bash печатает каждую команду перед выполнением

bash
PORT=${PORT:-8080}

Дефолтное значение переменной - обходит -u без отключения

bash
cmd || true

Игнорировать exit-code конкретной команды, не отключая -e глобально

bash
trap 'echo line $LINENO' ERR

Логировать строку где упал скрипт - must-have для длинных скриптов

§ см. также

  • signalsСигналы (SIGTERM, SIGKILL, SIGHUP)Сигнал - асинхронное уведомление процессу от ядра или другого процесса. TERM - попроси завершиться, KILL - убей сразу, HUP - перечитай конфиг.
  • process-and-pidПроцесс и PIDПроцесс - это запущенная программа со своим PID, памятью, открытыми дескрипторами и UID. Все процессы образуют дерево, корень - init (PID 1).
  • file-descriptorsFile descriptors (stdin, stdout, stderr)File descriptor - целое число, через которое процесс обращается к открытому файлу/сокету/pipe. У каждого процесса 0/1/2 = stdin/stdout/stderr.

§ упоминается в уроках

  • ›beginner-12-shell-scripting
  • ›intermediate-11-advanced-redirects
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки