Skip to main content
Bash is the glue of Linux systems work. I have written scripts ranging from one-liners to thousand-line deployment frameworks, and the patterns below represent hard-won lessons about what holds up at 3 AM when something breaks. Bash is not a general-purpose language — use Python for anything that needs data structures, HTTP calls, or complex logic — but for process orchestration, system automation, and operations tooling, a well-structured Bash script beats almost anything for portability and transparency.

Script Structure and Safety Flags

Every non-trivial script should open with this header. The few extra seconds it takes are worth avoiding hours of debugging half-completed state.
set -e — Without this, scripts happily continue after a failed cp or curl. With it, they stop and let you investigate.set -u — Catches typos in variable names. rm -rf $TMPDI/ (note the typo) would become rm -rf / without this flag.set -o pipefail — Without this, cat missing_file.txt | grep foo returns exit code 0 because grep succeeded — even though cat failed.IFS=$'\n\t' — The default IFS includes space, which causes word-splitting on filenames with spaces. Changing it prevents most quoting bugs.

Variables, Arrays, and String Operations


Conditionals


Loops


Functions


Error Handling and Exit Codes


Common Patterns


Useful One-Liners and Idioms


Complete Deployment Script Template

1

Save and make executable

2

Review the full template

3

Test with dry-run first

4

Run for real

The readonly SCRIPT_DIR pattern using BASH_SOURCE[0] is the correct way to get the script’s own directory even when the script is sourced or called via a symlink. Never use $0 alone for this purpose.

Linux Essentials

The core commands your scripts will call.

Troubleshooting

Debug failing scripts and the services they manage.

GitLab CI/CD

Integrate these scripts into automated pipelines.

Docker

Containerise the applications your scripts deploy.
Last modified on June 9, 2026