Bash scripting is the practice of writing programs for the Bourne Again Shell — the default interactive and scripting shell on almost every Linux distribution and the interpreter that runs inside container builds, CI job steps, systemd units, cron entries, cloud-init blocks and Kubernetes lifecycle hooks. A shell script is not a lesser kind of program; it is the program that runs before everything else is available, on a host where nothing else is installed yet.
The language is small and idiosyncratic. Everything is a string until you force it not to be, word splitting and globbing happen to unquoted expansions, exit codes rather than exceptions carry failure, and the conditional expression has two forms with meaningfully different behaviour. Learned properly, that model is fast and expressive: pipelines compose processes, parameter expansion does string surgery without spawning a subprocess, arrays and getopts give a script a real interface, and traps make cleanup deterministic.
Learned badly — which is the normal case — Bash scripting produces the failure class every operations team recognises. An unquoted variable containing a space destroys the wrong directory. A pipeline reports success because only the last command's exit status was checked. A script works on the author's machine and fails on the build agent because it assumed a shell option, a locale or a GNU flag. The difference between the two outcomes is a handful of habits: quoting, strict mode, checked exit codes, traps and a test for the script itself.
Why this skill matters now
Shell did not get replaced. It got embedded. Every Dockerfile RUN line, every CI job step, every entrypoint, every systemd ExecStart wrapper and every cloud-init block is shell, which means the average engineer now writes more Bash than they did a decade ago while treating it as less of a discipline.
That asymmetry is where incidents come from. Shell code sits at the most privileged point in the delivery chain — it runs as root, at build time, on every node — and it is routinely the least reviewed and least tested code in the repository. Teams that have adopted shellcheck, strict mode and a shell test harness see a measurable drop in broken builds and destructive operational mistakes; teams that have not are one unquoted variable away from an outage.
The skill in demand is not command trivia. It is writing shell that fails loudly, cleans up after itself, handles arguments properly, and behaves the same on a developer laptop, a build agent and a minimal container image.