Often enough shellscripts are the quickest solution to a given problem. However, writing shellscripts is just as hard as using any other programming language, as for example Valve (or rather Steam users) found out the hard way.
However, there are options you can set to make your shellscripts safer, which others have elaborated on already very nicely, therefore we will not look at it in detail here but instead recommend to take a look there.
Just briefly, these options summarize to
set -eEuo pipefail and make your script terminate on the first command exiting non-zero (including non-zero-exiting commands within a pipe chain) and when you try to use unset variables if set at the beginning of your shellscript.
The aforementioned error in the steam-uninstall-script would have been prevented by this.
However, you will have to set these options in every single script.
You could put them into your
.bashrc, for example, but not all scripts out there and on your system might be written with this option set in mind.
As adding these options into every single of your scripts might sound tedious, there is a better solution: writing a shell that is safe by default!
Implementing a safe bash
To do so we recognize that most scripts nowadays start with a line starting with the shebang:
In the case of bash this is typically
To be able to simply invoke a
safebash instead of
bash at this point, create a file
#!/bin/bash # exit immediately when a command fails set -e # abort on attempting to use an undefined variable (hello Valve! :)) set -u # set exitcode of a pipe chain to the exit code of the rightmost # command not exiting with zero, if there are any # in combination with -e this aborts on failure within a pipe chain set -o pipefail # make functions inherit ERR-traps, so that they fire when set -e takes effect there set -E # let subshells inherit these options export SHELLOPTS bash "$@"
and make it executable with
chmod +x /usr/local/bin/safebash
You can now start your shellscript-file with
#!/usr/local/bin/safebash instead of
#!/bin/bash and all the aforementioned options will be active without specifying anything explicitly.