Making a script robust
Bash's strict mode, trap for cleaning up, mktemp, errors on the error output with an exit status, idempotence and shellcheck: knowing where a script stops and what it leaves behind.
- 30 cards
- 5 topics
- Free
The outline, topic by topic
Each topic is weighted the way the exam weighs it.
- Concepts
- Questions
- Sort and link
- Scenarios
- Understand
A few cards from the deck
Strict mode: what is it?
Show the answer
Three Bash settings that make a script fail instead of carrying on:
set -e(stop on error),set -u(undefined variable) andset -o pipefail(failure in a pipe).Without it,
cd /nopefails and the script goes on withrm -rf *in the wrong folder. Butset -eignores failures in a test (if,&&,||): it does not replace checking for foreseeable cases.What happens when this script runs?
```bash
set -e
cd /nope
echo fini`- It stops on the
cderror, status 1, without printingfini - It prints the
cderror, thenfini, and returns status 0 - It prints
finiwith no error, sincecdonly changes folder - It asks for confirmation before carrying on with the script
Show the answer
It stops on the
cderror, status 1, without printingfinicd /nopefails (“No such file or directory”); underset -e, any simple command's failure stops the script with that command's status, here 1. Withoutset -e,finiwould be printed.- It stops on the
With set -u, reading a variable that was never defined stops the script with the message “unbound variable”; without it, Bash replaces it with ….
Show the answer
With set -u, reading a variable that was never defined stops the script with the message “unbound variable”; without it, Bash replaces it with an empty string.
It is what catches the typo
rm -rf "$dosier"/*: without-u, the empty variable gives/*. A deliberate default avoids the stop:${1:-default}.pipefail: what is it?
Show the answer
A setting that gives a pipe the status of the last command that failed, instead of that of its last command alone.
false | truereturns 0 by default: the failure offalsegoes unnoticed. Withset -o pipefail, it returns 1, andset -ecan then stop the script.Every night, the
/tmpfolder grows by 2 GB until the disk is full. The processing script creates a file withtmp=$(mktemp)and deletes it on its last line, but sometimes stops on an error. Which fix is right?- Add
trap 'rm -f "$tmp"' EXITjust aftermktemp - Put the
rm -fat the start of the script rather than the end - Replace
mktempwith a fixed name in/tmp - Add
set -uso the script stops earlier
Show the answer
Add
trap 'rm -f "$tmp"' EXITjust aftermktempWhen the script stops before its last line, the final
rmnever runs and the file stays. TheEXITtrap runs however the script ends. Armat the start would delete a file that does not exist yet.- Add