1

Say I have two functions, foo and bar:

foo() {
  FOO=foo
}

I can do this:

bar() {
  echo $FOO
}

$ bar
$ foo

But also I can do:

bar() {
  echo $1
}

$ bar $FOO
$ foo

And

foo() {
  local foo=foo
  return $foo
}

bar() {
  echo $1
}

$ bar foo
$ foo

How do I determine the scope of a variable, is global when it can be used in different functions, the same scripts, or/and across different scripts?

Is there a right way or a convention on how to manage functions with variables in bash?

  • 1
    Don't forget to double quote your variables when you use them. bar "$FOO" and echo "$1" for example. – Chris Davies Jul 05 '19 at 16:15
  • 2
    And don't use capitalised shell variables (only environment variables should be capitals). Yes many examples and tutorials get this wrong, but it is in the Unix best practice. – ctrl-alt-delor Jul 05 '19 at 16:55

1 Answers1

4

Environmental variable

When a program is invoked it is given an array of strings called the environment. This is a list of name-value pairs, of the form name=value.

Bash provides several ways to manipulate the environment. On invocation, the shell scans its own environment and creates a parameter for each name found, automatically marking it for export to child processes. Executed commands inherit the environment. The export and ‘declare -x’ commands allow parameters and functions to be added to and deleted from the environment. If the value of a parameter in the environment is modified, the new value becomes part of the environment, replacing the old. The environment inherited by any executed command consists of the shell’s initial environment, whose values may be modified in the shell, less any pairs removed by the unset and ‘export -n’ commands, plus any additions via the export and ‘declare -x’ commands.

These variables will be visible to all scripts executed within that environment

You can see them by executing the env command.

These are set either by using the export builtin or declare -x


Global variable

A global variable will be visible to everything within a single program (script) including child processes created by subshells/functions, but not across programs (scripts).

Any variable not specifically exported or declared as local will be a global variable.


Local variable

Variables local to the function may be declared with the local builtin. These variables are visible only to the function and the commands it invokes. This is particularly important when a shell function calls other functions.

Local variables "shadow" variables with the same name declared at previous scopes. For instance, a local variable declared in a function hides a global variable of the same name: references and assignments refer to the local variable, leaving the global variable unmodified. When the function returns, the global variable is once again visible.

The shell uses dynamic scoping to control a variable’s visibility within functions. With dynamic scoping, visible variables and their values are a result of the sequence of function calls that caused execution to reach the current function. The value of a variable that a function sees depends on its value within its caller, if any, whether that caller is the "global" scope or another shell function. This is also the value that a local variable declaration "shadows", and the value that is restored when the function returns.

For example, if a variable var is declared as local in function func1, and func1 calls another function func2, references to var made from within func2 will resolve to the local variable var from func1, shadowing any global variable named var.

These variables will only be visible to the function they are declared in and any child functions.

These variables must be specifically declared as local by using either the local builtin or simply using declare within the function.

jesse_b
  • 37,005