I'm learning bash scripting and found this on my /usr/share/bash-completion, line 305:
local cword words=()
What does it do? All tutorials online are just in the format
local var=value
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityAlthough I like answer given by jordanm I think it's equally important to show less experienced Linux users how to cope with such questions by themselves.
The suggested way is faster and more versatile than looking for answers at random pages showing up at Google search results page.
First, all commands that can be run in Bash without typing an explicit path to it such as ./command
can be divided into two categories: Bash shell builtins and external commands. Bash shell builtins come installed with Bash and are part of it while external commands are not part of Bash. This is important because Bash shell builtins are documented inside man bash
and their documentation can be also invoked with help
command while external commands are usually documented in their own man pages or take some kind of flag like -h, --help
. To check whether a command is a Bash shell builtin or an external command:
$ type local
local is a shell builtin
It will display how command would be interpreted if used as a command name (from help type
). Here we can see that local
is a shell builtin. Let's see another example:
$ type vim
vim is /usr/bin/vim
Here we can see that vim
is not a shell builtin but an external command located in /usr/bin/vim
. However, sometimes the same command could be installed both as an external command and be a shell builtin at the same time. Add -a
to type
to list all possibilities, for example:
$ type -a echo
echo is a shell builtin
echo is /usr/bin/echo
echo is /bin/echo
Here we can see that echo
is both a shell builtin and an external command. However, if you just typed echo
and pressed Return a shell builtin would be called because it appears first on this list. Note that all these versions of echo
do not need to be the same. For example, on my system /usr/bin/echo
takes --help
flag while the Bash builtin one doesn't.
Ok, now when we know that local
is a shell builtin let's find out how it works:
$ help local
local: local [option] name[=value] ...
Define local variables.
Create a local variable called NAME, and give it VALUE. OPTION can
be any option accepted by `declare'.
Local variables can only be used within a function; they are visible
only to the function where they are defined and its children.
Exit Status:
Returns success unless an invalid option is supplied, an error occurs,
or the shell is not executing a function.
Note the first line: name[=value]
. Everything between [
and ]
is optional. It's a common convention used in many man pages and form of documentation in *nix
world. That being said, command you asked about in your question is perfectly legal. In turn, ...
character means that previous argument can be repeated. You can also read about this convention in some versions of man man
:
The following conventions apply to the SYNOPSIS section and can be used
as a guide in other sections.
bold text type exactly as shown.
italic text replace with appropriate argument.
[-abc] any or all arguments within [ ] are optional.
-a|-b options delimited by | cannot be used together.
argument ... argument is repeatable.
[expression] ... entire expression within [ ] is repeatable.
So, at the end of the day, I hope that now you'll have an easier time understanding how different commands in Linux work.
var=()
, but I suppose that is a bit much to figure out without even knowing the name of what you're looking for. ;)
man
but I did not know about type
or help
or that help
worked on bash keywords.
May 6, 2019 at 15:09
Your example
local cword words=()
defines a scalar variable cword
and an empty array words
in the scope of the current function.
local
simply declares a variable to have scope only in the currently-defined function, so that the main executing environment cannot "see" the value. You can't use local
outside a function. Example
func() {
nonlocal="Non local variable"
local onlyhere="Local variable"
}
func
echo $nonlocal
echo $onlyhere
Output: Non local variable
So $onlyhere
wasn't visible outside the scope of the function.
local foo=value
and local bar=()
local
. foo
is a scalar variable, whereas bar
is an array.
The local
keyword can take multiple variables. Providing the variable with a value is optional. Your example declares two variables, cword
and words
. The words
variable is assigned an empty array.
It should be noted that Bash is dynamically scoped, which means local
doesn't behave how you might expect from other languages.
Observe:
#!/usr/bin/env bash
x=15
print1 () {
echo "I am printing $x"
}
print2 () {
local x=44
print1
}
print1 # prints "I am printing 15"
print2 # prints "I am printing 44"
print1 # prints "I am printing 15"
So essentially this means local
doesn't mean "local variable" it means "locally redefined global variable"
Greetings users of Unix & Linux SE / @alex-santos, here is a full answer to the question a single, comprehensive response!
local cword words=()
What does it do?
"The local keyword can take multiple variables. Providing the variable with a value is optional. Your example declares two variables, cword and words." (Thanks @jordanm!)
A possible caveat is SC2155 in that you should declare and assign separately.
That being said it will work except for using multiple declare options between the parameters. Also, note that the declare parameters will apply to all variables (in this case -i). See here Can one declare multiple local variables in one line
The words
variable is assigned an empty array. Because the variable is set to a local
access level, it must be declared within a shell function. A local
variable will override a global variable with the same name without throwing an error. The local variable will only replace the global variables' value during the execution of the function. The global variables' value will be the one being managed outside of any overriding function scope.
Furthermore, a variable that has only been declared within function scope and has not been declared globally or imported will see the code from several of the existing answers below which illustrated this case and the code I added to cover the other cases described below.
*Cheers to @electric-coffee, @Otheus for illustrating one of the cases the 1st function/local scope example below and to *
Using shell functions to demonstrate local/global variables given all permutations of access and scopes.
exampleFunction() {
nonlocal="Non local variable"
local localToExampleFunctionOnly="Local variable"
}
# Prints "Non local variable".
echo $nonLocal
# Set the globally accessible variable value.
globalVariable="Globally accessible variable."
# Prints "Globally accessible variable." to the console from within
# the global context.
echo $globalVariable;
exampleFunction() {
globalVariable="Locally accessible variable."
# Prints "Locally accessible variable."
echo $globalVariable;
}
# Call function, printing "Globally accessible variable." to the console from within
# the global context.
exampleFunction
# Prints "Globally accessible variable." to the console
# from within the global runtime environment (the original value set to globally accessible scope).
echo $globalVariable
# Set the globally accessible variable value.
globalVariable="Globally accessible variable."
# Prints "Globally accessible variable." to the console from within
# the global context.
echo $globalVariable
exampleFunction() {
# Prints "Globally accessible variable." to the console
# from within the function scope context.
echo $globalVariable;
}
# Call function the first time
exampleFunction
# Prints "Globally accessible variable." to the console
# from within the global runtime environment.
echo $globalVariable
# Update the globally accessible variable to a new value.
globalVariable="That's all the cases for scoping I can think of..."
# Prints "That's all the cases for scoping I can think of..." to the
# console from within the global context.
echo $globalVariable;
# Call function the last time, now that the value has been updated
# from global and local scope.
# Prints "That's all the cases for scoping I can think of..."
# from the `exampleFunction`.
# Prints "That's all the cases for scoping I can think of..." to the
# console from within the function scoped context, re-referencing
# the updated global value and printing it to the terminal's output.
echo $globalVariable
Try to think of function scope as code-space where your local variables can be modified or referenced when executed, without any side effects from the "outer" environment.
To summarize, the words=()
is the second local variable being set in this shell script and is of type Array due to the words=()
syntax. The ()
portion initializes to an empty array accessible after its declaration via $words
. Access and element via $words[$elementNumericIndex] and set during initialization like
words=("bob" "john" "steve")or
words[0]="bob"`.
*Here is the full documentation for using in bash, nix shell variables (setting, accessing, and more).
https://tldp.org/LDP/Bash-Beginners-Guide/html/sect_10_02.html
All tutorials online are just in the format
local var=value
As you may already know, this is the more commonly used single value->variable assignment, which is used for maintaining key-to-value variable relationships which encourage code readability, reduces redundancy, and improves performance when re-using the referenced value instead of redeclaring (hard coding the value repeatedly), promotes best practice, and reduces errors due to "fat fingering" a key while reading/setting/declaring the value from the repeated hard-coded version vs the friendly-named variable (also most modern IDE's and even editors support plugins or natively the ability to autocomplete your variables once declared and if in scope and dependant on the position of the cursor while the application is being composed).
I combined some of the great answers provided on this thread in order to answer the OP's question fully and concisely.
I stumbled on this and realized that IMO the most correct and succinct way to fully answer our OP's answer is scattered amongst @jordanm, @electric-coffee, @arkadiusz-drabczyk (directs us to a good response output directly from your local terminal's manual in order to address OP's question about declaring a function scoped variable using local
.
local cword words=()
local var=value
Some helpful links: