Practices

Coding Standards and Tips

  • Always use the below script header to make BASH behave sanely
  • never use UPPER_CASE variables, always use camelCaseVariables
  • use [[ "double square brackets" != ""]] double square brackets for string comparison
  • use (( 1 > 0)) double round brackets for maths type comparisons
  • Always have a usage function and check at least the number of paramters at the top of the script
  • Always check to make sure the script is being run as the correct user
  • If you want to have optional parameters, use the ${1:-'default-value'} default-value symbol :- to set the default
  • wrap things you are happy to fail with set +e and set -e to temporarily and clearly disable strict error handling
  • Use echo "comments" to echo out useful info and also act as comments
  • use bash -$- when running scripts from inside your script so that -x will propogate through to sub scripts
  • always use local varname inside functions to enforce function scope
  • use readonly varname where possible to prevent variables being overwritten accidently
  • Where possible, try to use simple string comparision rather than the less obvious conditionals.
  • Always make your scripts idempotent That means that the script can safely be re-run and will always ensure the same result.
  • When writing to files, the following pattern is the easiest and most reliable
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ## Append to File
    cat <<EOF >> /path/to/file
    content you are writing to the file is here and can include "quotes" of 'both' kinds
    EOF
    
    ## Overwrite to File
    cat <<EOF > /path/to/file
    content you are writign to the file is here and can include "quotes" of 'both' kinds
    EOF
    
  • For debugging, run scripts with bash -x. For even more debug info use bash -vx

Bash Step Through Debugging

For those really difficult to debug BASH issues, you can use the step through debugging mode (unofficial)

Just paste this snippet into the top of your script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Bash Step Through Debugging Mode! #############################################
echo "
#################################################################################
YOU'RE ENTERING BASH STEP THROUGH DEBUGGING MODE

You will see the code as it is read,
and the code as it is evaluated and executed.

Hit return to move to move through the code,
hit [ctrl]+[c] to stop execution
#################################################################################
"
set -vx
trap read debug
# Bash Step Through Debugging Mode Ends #########################################

Redirecting Output

By default, BASH uses 2 outputs:

  • "Standard Error:" stderr
  • "Standard Oout": stdout

Read More:

It is quite usual to want to redirect stderr to stdout, for things like logging

Redirect All Stderr to Stdout in a script with exec

Add this to the top fo your script and all subsequent stderr will be redirected to stdout - this includes output from set -x

1
exec 2>&1

Read More:

Check If Variable Is Set

You can use the following snippet to check if a variable has been set:

1
2
3
4
5
6
if [ -z "${var+x}" ]
then
    echo "var is unset";
else
    echo "var is set to '$var'";
fi

-z checks that the length of the string is zero. If $var is not set then "${var+x}" evaluates to "". If $var is set then "${var+x}" evaluates to "x".

Note

You can invert this by using -n which checks that the length of the string is greater than zero.

Read More:

Script Header

Use this as a script header for every BASH script.

  • Normalises the current directory to the script location
  • Sets up strict mode so that things fail sensibly
  • Gives you a more useful IFS (internal field separator), with the ability to switch back to standard IFS should you wish.
  • Spits out a useful and consistent header so you can see where, what and how is being run

Tip

To automatically get this inserted whenever you create a bash file in PhpStorm go to Setting -> Editor -> File and Code Templates and update the bash template