bashvariableslocal

Bash local variable scope best practice


I've seen that some people when writing bash script they define local variables inside an if else statement like example 1

Example 1:

#!/bin/bash

function ok() {
  local animal

  if [ ${A} ]; then
     animal="zebra"
  fi

echo "$animal"
}

A=true
ok

For another example, this is the same:

Example 2:

#!/bin/bash
function ok() {

  if [ ${A} ]; then
     local animal
     animal="zebra"
  fi

echo "$animal"
}

A=true
ok

So, the example above printed the same result but which one is the best practice to follow. I prefer the example 2 but I've seen a lot people declaring local variable inside a function like example 1. Would it be better to declare all local variables on top like below:

function ok() {
 # all local variable declaration must be here
 
 # Next statement
 
}

Solution

  • the best practice to follow

    Check your scripts with https://shellcheck.net .

    Quote variable expansions. Don't $var, do "$var". https://mywiki.wooledge.org/Quotes https://www.shellcheck.net/wiki/SC2086

    For script local variables, prefer to use lowercase variable names. For exported variables, use upper case and prefixed unique variable names.

    Do not use function name(). Use name(). https://wiki.bash-hackers.org/scripting/obsolete (archive.org http://web.archive.org/web/20170123130003/http://wiki.bash-hackers.org/scripting/obsolete ).

    Document the usage of global variables a=true. Or add local before using variables local a; then a=true. https://google.github.io/styleguide/shellguide.html#s4.2-function-comments

    scope best practice

    Generally, use the smallest scope possible. Keep stuff close to each other. Put local close to the variable usage. This is like the rule from C or C++, to define a variable close to its usage, but unlike in C or C++, in shell local declaration and assignment should be on separate lines, see https://www.shellcheck.net/wiki/SC2155 .

    Note that your examples are not the same. In the case variable A (or a) is an empty string, the first version will print an empty line (the local animal variable is empty), the second version will print the value of the global variable animal (there was no local). Although the scope should be as smallest, animal is used outside of if - so local should also be outside.