Hardening Bash

From Zanecorpwiki

Jump to: navigation, search

Based on GNU bash 3.2.39(1)

'set -u'. Causes the script to halt if it encounters an undefined variable.

'set -e'. This will cause the script to halt on any command completing wit a non-zero exit status. There are a few caveats:

  • sub-shells that exit with non-zero do not trip the '-e' check in the parent shell; thus:
set -e
false
echo 'foo'

Results in no output, but:

set -e
(false)
echo 'foo'

Results in 'foo'.

  • however, the check within the sub-shell is still active so:
set -e
(false; echo -n 'bar')
echo 'foo'

Output 'foo', not 'barfoo'

  • it seems to combination of options change this behavior so the best you can do is invoke sub-shells like so:
set -e
(false; echo -n 'bar') || false
echo 'foo'

Set a trap to provide some info on exit. Just exiting is nice, but it's good to know the script failed. Solution: trap errors with something like:

function onerr() {
  echo "exited with status '$1' at line $2."
  exit $1
}
trap 'onerr ${?} ${$LINENO}' ERR

Unset the error trap and options when necessary. Some non-standard commands, or areas of the script where errors are permissible should be preceded be:

set +e
trap - ERR

Why is this Necessary?

You may ask why this is not the default behavior? Well, maybe it should be, but think of the origins of bash as an interactive shell. If you turn on these options in that environment, you're login shell will exit every time you type in a command or reference a variable that doesn't exist. With '-e', if some other process fails through no fault of your own, it can bring down your shell.

It would be nice for the script writer if these options were on by default and explicitly disabled for interactive shells, but that's just the developer point of view.

References

Personal tools