Shell Coding Convention

Improvements? Suggestions? email dna@hola.org

Coding conventions used by other companies: google

General

In general, most of C coding convention apply to Bash coding convention, for example:

  • - Indentation is always one shift-width(4):
  • - case has the same indentatio level and switch
  • - ...

Function parameters

Function parameters should define local their names, not use $1, $2...

foo()
{
    cp $1 $2
}
foo()
{
    local src=$1 dst=$2
    cp $src $dst
}

returning a string value: RS="the value"

install_dir()
{
    echo "/usr/local/bin"
}

install app.sh `install_dir`
install_dir()
{
    RS="/usr/local/bin"
}

install_dir
install app.sh $RS

returning an array value: RA=(the values...)

install_paths()
{
    RA=(/usr/local/bin /usr/local /etc)
}

install_paths
for p in "${RA[@]}"; do try_install "$p"; done

returning multiple string/array values

returning multiple string/array values use RS_{name} or RA_{name}:

install_app()
{
    RS_dir=/usr/local/bin
    RA_paths=(/usr/local/bin /usr/local /etc)
}

install_app
try_install "$RS_dir" "${RA_paths[@]}"

argv handling and usage()

argv handling and usage(): use shift to process, and always have usage() function:

usage()
{
    echo "usage: ..."
    exit 1
}
while [ "${1:0:1}" = - ]; do
    case "$1" in
    --option)
        ... set option ...
        ;;
    --option-with-arg)
        shift
        if [ -z "$1" ]; then
            usage
        fi
        ... use *argv to set option ...
        ;;
    *)
        usage
        ;;
    esac
    shift
done
... handle arguments left in argv ...
if [ -n "$1" ]; then
    usage
fi
... start working ...

Where integer operations are relevant

Where integer operations are relevant, use ((C_EXPRESSION)) instead of [SHELL_EXPRESSION]:

if [ "$prep_inc" == 1 ]; then
    enable_prep
fi
if ((prep_inc)); then
    enable_prep
fi

SHELL EXPRESSIONS

In SHELL EXPRESSIONS use [[ ]] instead of [ ] when AND/OR is needed:

if [ -z "$install_dir" -o ! -d "$install_dir" ]; do
    install_the_dir
fi
if [[ -z "$install_dir" || ! -d "$install_dir" ]]; do
    install_the_dir
fi

When the script is included in other scripts

When the script is included in other scripts, use the following method to avoid multiple includes:

  if ((__FULL_PATH_FROM_PGK_FILENAME__)); then
      return 0
  fi
  __FULL_PATH_FROM_PGK_FILENAME__=1

example:
  if ((__SYSTEM_SCRIPTS_JTOOLS_FUNCTIONS_SH__)); then
      return 0
  fi
  __SYSTEM_SCRIPTS_JTOOLS_FUNCTIONS_SH__=1

Quotation:

the sign $@ is a special sign for all the parameters passed to the function.
when quoting it "$@" bash will quote each parameter seperatly.
if you want to use all the parameters, you should use an array:
cmd=("$@")
cmd=("${cmd[@]}" "some other text")
"${cmd[@]}"
The above three lines, save the parameters into an array, adds to it another
value and then us it as a bash command.

Quotation should always take under consideration when passing vars and arrays to other functions or when excecuted as a command.