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.