4 ms·
Advice at a higher level: don’t try too hard to handle error cases in your scripts. The best shell scripts are a list of imperative instructions to get somethi
by gorgoiler 5y ago
Advice at a higher level: don’t try too hard to handle error cases in your scripts.
The best shell scripts are a list of imperative instructions to get something done. If an error occurs, bail as early as possible and with a useful message. Don’t try any harder than that.
For example:
if ! complex_function
then
handle_error
fi
…doesn’t work as you’d expect because the “if” context changes the rules of set -e in complex_function. It’s much better to have complex_function crash your script with a helpful error message that the operator can ameliorate.
You may have a clever way of solving this problem, but the cleverer your solution gets, the further you diverge from the core language of shell scripting. You will suffer the lisp/Ruby problem of every script being in its own unique language that’s based on but not identical to the language with which your colleagues are familiar.
One shouldn't dismiss shell scripts completely – the command line is the primary interface to Unix and with more and more idempotent commands showing up every year ("ip route replace") it only gets easier to write simple, imperative lists of commands.
- neves 5y agoI agree. You must fail fast. My best shell advice is to put these commands at the beginning of every script: set -e # stop scripts on errors set -u # stop script if undefined var set -o pipefail # stop script if there's a pipe failure Use them to have a saner life.
- misnome 5y agoAnd you can compact them to set -euo pipefail
- l0b0 5y agoMy favourite set of pragmas: set -o errexit -o noclobber -o nounset -o pipefail shopt -s failglob inherit_errexit These are all easy to find in the Bash manual.
- creamytaco 5y agoFor most uses, I consider all of these unwanted at best and potential disasters at worst. If you use them, make sure you understand exactly what each of these do. If you just follow a dictum you found on HN blindly and just copy-paste them, you're in for a world of hurt. Example for set -e: https://mywiki.wooledge.org/BashFAQ/105 https://mywiki.wooledge.org/BashFAQ/105
- hnlmorg 5y agoThis was one of the annoyances that I aimed to solve with my own shell, murex. It has predictable if blocks but also try blocks. I used to be an advocate for `set -e` etc but these days I've come to the conclusion that the POSIX standard just needs to be retired for simple shell scripts, even if it is just for personal use. And it doesn't have to be my shell language that replaces it, but it shouldn't be something aiming for Bash/sh compatibility. This is probably going to be an unpopular opinion though but I base it on years of Bash/sh use and then getting fed up with it enough to write me own shell + scripting language. As for anything that needs to be used and maintained by a team, that's probably around the time you have to question if shell script is even the right solution and whether you need to break out into Python (though Python has it's own issues too so one has to make an informed decision based on your own business requirements).
- jgtrosh 5y agoAlso the fact that shell IF condition is backwards from other programming languages always bugs me In C we always write `if (func()) handle_error` for the standard 0=success convention, and reading shell IFs is mentally straining
- majkinetor 5y agoWhat a nasty shell. You can't even error check like a man.
- majkinetor 5y agoOK, not nasty. Terrible. Outdated. And I even like old things, but bash never wakes up any nostalgy in me, it just wakes up a monster.