linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Simulator
  • Knowledge base
  • Interview prep
Index
Categories
All entries
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
home/linux/kb/Processes & resources/bash-strict-mode

kb/processes ── Processes & resources ── intermediate

Bash strict mode: set -euo pipefail

Three flags at the top of a bash script that turn it from forgiving into fail-on-the-first-error. Without them, bugs pile up silently.

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

Why you need it

By default bash does not stop on errors. It keeps running the script as if nothing happened:

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

▸error, but the script keeps going

rm -rf /tmp/dest/*            

▸now this deletes SOMETHING ELSE

Without strict mode a script like this corrupts data silently. Strict mode is three flags that must sit at the top of any non-trivial script:

bash
set -euo pipefail

What each flag does

FlagLong nameEffect
-eerrexitStop at the first command with exit code != 0
-unounsetStop if you use a variable that was never set
-o pipefailpipefailA pipe counts as failed if any stage failed

Without pipefail, the command cmd1 | cmd2 takes its exit code from the last command in the pipe. So false | true returns 0 (success), because bash looks only at true. With pipefail, bash sees that false failed and the pipe fails too.

The idiom

The standard prelude of every production script:

bash
#!/usr/bin/env bash
set -euo pipefail
# your code goes here

Sometimes you add -x for debugging (it traces every command to stderr):

bash
set -euxo pipefail   # with tracing

Or you turn it on temporarily:

bash
set -x
some_buggy_command
set +x   # turn it off

When to disable it locally

Sometimes -e gets in the way: a command may return != 0 on purpose, and that is fine. Then use || true or an explicit check:

bash
# diff returns 1 when the files differ. For us that is not an error
diff a.txt b.txt > result.txt || true
# Alternative: switch off -e for a single command
if some_check; then
    echo ok
else
    echo "check failed but we're fine with that"
fi

With -u there is a similar trap. ${VAR:-default} gives a default value when the variable is not set, without stopping:

bash
PORT=${PORT:-8080}    # 8080 if PORT is not set
echo "${OPTIONAL:-}"  # empty string instead of an error

Alternatives and fine points

  • set -E - trap ERR handlers are inherited inside functions (off by default)
  • set -o functrace - the same for DEBUG/RETURN traps
  • shopt -s inherit_errexit - -e is inherited inside command substitution $(...) (also off by default)

The full defensive prelude you see in production:

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

The standard defensive prelude. Required at the top of every script

bash
set -x

Turn on tracing: bash prints each command before running it

bash
PORT=${PORT:-8080}

Default value for a variable. Works around -u without turning it off

bash
cmd || true

Ignore the exit code of one command without disabling -e globally

bash
trap 'echo line $LINENO' ERR

Log the line where the script failed. A must-have for long scripts

§ см. также

  • signalsSignals (SIGTERM, SIGKILL, SIGHUP)A signal is an asynchronous notification to a process from the kernel or another process. TERM asks it to quit, KILL kills it now, HUP reloads config.
  • process-and-pidProcess and PIDA process is a running program with its own PID, memory, open descriptors, and UID. Every process forms a tree rooted at init (PID 1).
  • file-descriptorsFile descriptors (stdin, stdout, stderr)A file descriptor is an integer a process uses to reach an open file, socket, or pipe. Every process gets 0/1/2 = stdin/stdout/stderr.

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

  • ›beginner-12-shell-scripting
  • ›intermediate-11-advanced-redirects
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies