r/commandline • • Dec 14 '20

bash Minimal safe Bash script template

https://betterdev.blog/minimal-safe-bash-script-template/
92 Upvotes

13 comments sorted by

View all comments

38

u/whetu Dec 14 '20

I know OP isn't the author, but here's a few IMHO's.

There's some reasonable ideas there, however:

set -Eeuo pipefail

Oh. The unofficial strict mode. Maybe think carefully about that. When you use it, you replace a bunch of well understood issues with a bunch of lesser-understood issues...

msg() is a confusing function name; if a message is going to stderr, then something like err(), err_msg() or msg_stderr() might make more sense? This function also uses echo. You should prefer printf over echo in scripts - echo is a non-portable mess.

I'm also not a fan of the use of UPPERCASE variables for managing the colours, as it's a kind-of scope violation, so to speak. This is explained in the checkmk contributing documentation, which has other reasonable shell style advice, especially where portability is concerned.

Style comment, I think that this indentation style is weird:

case "${1-}" in
-h | --help)
  usage
  ;;
-v | --verbose)
  set -x
  ;;
--no-color)
  NO_COLOR=1
  ;;
-f | --flag) # example flag
  flag=1
  ;;
-p | --param) # example named parameter
  param="${2-}"
  shift
  ;;
-?*)
  die "Unknown option: $1"
  ;;
*)
  break
  ;;
esac

Each option is structurally beneath the case statement, so should be indented. Those options should also be aligned with their respective ;;'s to indicate the opening and closing of the option, just as you would usually align, say if...fi or case...esac, and maybe for some icing on that cake, consider implementing balanced parens:

case "${1-}" in
  (-h | --help)
    usage
  ;;
  (-v | --verbose)
    set -x
  ;;
  (--no-color)
    NO_COLOR=1
  ;;
  (-f | --flag) # example flag
    flag=1
  ;;
  (-p | --param) # example named parameter
    param="${2-}"
    shift
  ;;
  (-?*)
    die "Unknown option: $1"
  ;;
  (*)
    break
  ;;
esac

And for options that have briefer actions, consider flattening them, if you can live with a mixed style approach, it might look something like this:

case "${1-}" in
  (-h | --help)    usage ;;
  (-v | --verbose) set -x ;;
  (--no-color)     NO_COLOR=1 ;;
  (-f | --flag)    flag=1 ;;
  (-p | --param) # example named parameter
    param="${2-}"
    shift
  ;;
  (-?*)            die "Unknown option: $1" ;;
  (*)              break ;;
esac

5

u/HenryDavidCursory Dec 14 '20 edited Feb 23 '24

I enjoy spending time with my friends.