local
Declare variables with local scope in functions
TLDR
Declare a string variable with the specified value
Declare an integer variable with the specified value
Declare an array variable with the specified value
Declare an associative array variable with the specified value
Declare a readonly variable with the specified value
Display help
SYNOPSIS
local [options] [name[=value] ...]
PARAMETERS
-a
Declares an indexed array variable.
-A
Declares an associative array variable.
-i
Declares an integer variable.
-n
Declares a nameref (name reference) variable, which acts as an alias for another variable. This is particularly useful for passing variables by reference to functions.
-r
Declares a readonly variable; its value cannot be changed after initialization within the function's scope.
-x
Marks the variable for export to child processes spawned from within the function. While local, it would be exported if a subshell or external command were executed from the function.
-g
(Bash 5.0+) Declares a global variable from within a function, overriding the default local scope. This option is useful for intentionally creating or modifying a global variable from inside a function, such as when a function is designed to set a global status flag.
-p
Displays the attributes and values of currently defined local variables. If no name is provided, all local variables accessible in the current function scope are shown.
name[=value]
The name of the variable to declare, optionally initialized with a value. Multiple variables can be declared on a single line, separated by spaces.
DESCRIPTION
The local command is a shell built-in, primarily used within shell functions in environments like Bash, ksh, and zsh. Its fundamental purpose is to define variables whose scope is restricted to the function in which they are declared. This means the variable exists only for the duration of the function's execution and is not accessible from outside the function, nor does it affect variables with the same name in the global scope or in calling functions.
Using local is crucial for writing robust and modular shell scripts. It helps prevent unintended side effects, such as a function inadvertently modifying a global variable with the same name, or causing naming conflicts between different parts of a script. It enhances code reusability by ensuring functions are self-contained and operate on their own set of variables.
While similar to the declare built-in, local implicitly applies the 'local' attribute, making variables function-scoped by default. It supports many of the same options as declare for specifying variable attributes like type (e.g., integer, array) or behavior (e.g., readonly, exported).
CAVEATS
Behavior Outside Functions: If local is invoked outside of a function, it behaves identically to the declare or typeset built-ins, creating or modifying a global variable. This is a common source of confusion and unexpected behavior, as it loses its 'local' scoping property.
Variable Shadowing: When a local variable is declared with the same name as a global variable, the local variable 'shadows' the global one within the function's scope. Any operations on that variable name inside the function will affect the local variable, leaving the global variable's value unchanged. Once the function exits, the local variable is destroyed, and the original global variable becomes accessible again.
Dynamic vs. Lexical Scope (Historical Note): In older versions of Bash (pre-5.0), local variables were effectively dynamically scoped for functions called by the current function (i.e., a called function might see the local variable if it didn't declare its own). Modern Bash versions and good scripting practices favor a more predictable lexical scope. The introduction of local -g in Bash 5.0 helps manage intentional interaction with global variables, promoting cleaner scope management.
USAGE EXAMPLES
Here are a few examples demonstrating the use of local:
Basic Local Variable (Shadowing Global):
my_function() {
local message="Hello from function"
echo "Inside: $message"
}
message="Hello from global"
echo "Before: $message"
my_function
echo "After: $message"
Output:
Before: Hello from global
Inside: Hello from function
After: Hello from global
Notice how the global 'message' was unaffected by the function's local 'message'.
Local Readonly Variable:
another_function() {
local -r MY_CONSTANT=123
echo "Constant: $MY_CONSTANT"
# MY_CONSTANT=456 # This line would cause an error: readonly variable
}
another_function
Using local -g (Bash 5.0+ to create/modify global):
update_global() {
local -g GLOBAL_VAR="New Global Value"
}
GLOBAL_VAR="Initial Global Value"
echo "Before: $GLOBAL_VAR"
update_global
echo "After: $GLOBAL_VAR"
Output:
Before: Initial Global Value
After: New Global Value
RETURN STATUS
The local built-in returns an exit status of zero (0) upon successful declaration or modification of variables. A non-zero status (typically 1) is returned if an error occurs, such as attempting to use an invalid option, providing an invalid variable name, or trying to declare a variable as readonly that is already set and non-readonly (without using local -g to manage global scope implications). For instance, if you try to declare a variable with an invalid name or an option that doesn't exist, local will return a non-zero exit status.
HISTORY
The concept of explicitly scoped variables within functions gained prominence in shell scripting languages to enhance modularity and prevent unintended side effects common with globally scoped variables. The typeset built-in in the Korn Shell (ksh) was one of the early implementations providing variable attributes and local scope.
Bash adopted this concept, introducing its own local built-in specifically to declare variables with function-local scope. This was a significant step towards enabling more robust and maintainable shell scripts, allowing developers to write self-contained functions without worrying about polluting the global namespace. The design aimed to simplify variable management within functions, making code more predictable and reusable.
Over the years, Bash has evolved, with notable enhancements like the introduction of local -g in Bash 5.0. This option provides a way to explicitly declare or interact with global variables from within a function, offering greater control over variable scope in complex scripting scenarios, while still emphasizing the primary role of local for function-specific variables.
SEE ALSO
declare(built-in), typeset(built-in), export(built-in), readonly(built-in), bash(1)