Bash declare

Most programmers can get by without knowing about declare in bash. Good thing we aren't most programmers. The leverage you get out of using declare and variable attributes is huge. It goes way beyond creating arrays and integer variables.

Using declare

One thing you learn later in bash is to use certain builtin commands. Declare in bash is no exception. Here we cover how to use the builtin declare to modify the attributes of bash variables allowing you to create of arrays, list functions, integers, and much more.

bash -c "help declare"
declare: declare [-aAfFgilnrtux] [-p] [name[=value] ...]
    Set variable values and attributes.

    Declare variables and give them attributes.  If no NAMEs are given,
    display the attributes and values of all variables.

Options:

Declare takes [-aAfFgilnrtux] [-p] as options. 

[-aAfFgilnrtux] affects attribute assignment.

[-p] affects display of attributes

Options for functions:

  -f        restrict action or display to function names and definitions

  -F        restrict display to function names only (plus line number and
                source file when debugging)

Option to list bash variable attributes:

  -p        display the attributes and value of each NAME

When you need to get variable attributes in bash declare -p variable_name comes in handy. The -p option can be used to exclude functions from output. Additionally, the effect of the -p option is canceled out when combined with either the -f option to include functions or the -F option to include only function names.

Options which set attributes:

-a to make NAMEs indexed arrays (if supported)

-A to make NAMEs associative arrays (if supported)

-i to make NAMEs have the 'integer' attribute

  -g        create global variables when used in a shell function; otherwise
            ignored

  -l        to convert NAMEs to lower case on assignment

  -n        make NAME a reference to the variable named by its value

  -r        to make NAMEs readonly

  -t        to make NAMEs have the `trace' attribute

  -u        to convert NAMEs to upper case on assignment

  -x        to make NAMEs export
Using `+' instead of `-' turns off the given attribute.

    Variables with the integer attribute have arithmetic evaluation (see
    the `let' command) performed when the variable is assigned a value.

    When used in a function, `declare' makes NAMEs local, as with the `local'
    command.  The `-g' option suppresses this behavior.

    Exit Status:
    Returns success unless an invalid option is supplied or a variable
    assignment error occurs.

The bash builtin command declare provides access to variable attributes within the scope of a bash program.

Here is a list of ways declare may be used.

  • declare an arrays
  • declare namerefs
  • dump variables
  • test functions
  • give variable attributes
  • remove variable attributes
  • list attributes
  • make variable read-only
  • make variable an integer
  • make variable cast into lowercase on assignment
  • make variable cast into uppercase on assignment
  • make variable or function available in subshells

to declare an array

declaring arrays in bash

indexed arrays

declare -a in bash

The -a option adds the indexed array attribute to the variable name provided to the declare command.

declare indexed array variable

#
# declare an array
#
declare -a VARIABLE 

set indexed array key value

Array key values may be set on initialization or afterwords. Indices inherit the integer attribute inside square brackets ("[]"). Using declare -p on an indexed array will list all array keys along with their corresponding assigned values.

#
# declare an array and set key values
#
declare -a arr=(1) # arr[0]=1
arr[1]=$(( arr[0] + 1 ))
echo ${arr[0]} # 1
echo ${arr[1]} # 2
for i in {1..10}
do
 arr[i]=$(( arr[i-1] + arr[i-2] ))
done
echo ${arr[i]} # 199
declare -p arr
## expect
#declare -a arr=([0]="1" [1]="3" [2]="4" [3]="7" [4]="11" [5]="18" [6]="29" [7]="47" [8]="76" [9]="123" [10]="199")

associative arrays, hashes, map, dictionary, or collection of (key,value) pairs

Associative arrays hold key value pairs also called hashes. Unlike indexed arrays, their indices are not limited to integer values. That is, associative array keys may be any string.

declare -A in bash

The -A option adds the associative array attribute to the variable name provided to the declare command. Note that declaring an associative array within a function will force local scope. To declare scope outside and use in a function omit the associative array declaration command line.

declare associative array

#
# declare an associative arrays
#
declare -A VARIABLE 

local associative array

foobar() { # foo w/ bar
  echo -n ${FUNCNAME}:
  ## note that local is not required in the case of declare -A
  declare -A arr
  arr["key"]=value2
  bar
}
rab() { # declares arr local
  echo -n ${FUNCNAME}:
  local arr
  declare -p arr
}
bar() { # may inherit global arr
  echo -n ${FUNCNAME}:
  declare -p arr
}
foo() { # declare arr local to function
  echo -n ${FUNCNAME}:
  ## note that local is not required in the case of declare -A
  declare -A arr
  arr["key"]=value2
  declare -p arr
}
{ echo -n : ; declare -p arr 2>/dev/null || echo no variable named arr 1>&2 ; }
foo
{ echo -n : ; declare -p arr 2>/dev/null || echo no variable named arr 1>&2 ; }
( declare -A arr ; arr["key"]=value ; declare -p arr ; )
{ echo -n : ; declare -p arr 2>/dev/null || echo no variable named arr 1>&2 ; }
{ declare -A arr ; arr["key"]=value ; declare -p arr ; }
{ echo -n : ; declare -p arr 2>/dev/null || echo no variable named arr 1>&2 ; }
foo
{ echo -n : ; declare -p arr 2>/dev/null || echo no variable named arr 1>&2 ; }
( declare -A arr ; arr["key"]=value3 ; declare -p arr ; )
{ echo -n : ; declare -p arr 2>/dev/null || echo no variable named arr 1>&2 ; }
bar
{ echo -n : ; declare -p arr 2>/dev/null || echo no variable named arr 1>&2 ; }
rab
{ echo -n : ; declare -p arr 2>/dev/null || echo no variable named arr 1>&2 ; }
foobar
{ echo -n : ; declare -p arr 2>/dev/null || echo no variable named arr 1>&2 ; }
## expect
#:no variable named arr
#foo:declare -A arr=([key]="value2" )
#:no variable named arr
#declare -A arr=([key]="value" )
#:no variable named arr
#declare -A arr=([key]="value" )
#:declare -A arr=([key]="value" )
#foo:declare -A arr=([key]="value2" )
#:declare -A arr=([key]="value" )
#declare -A arr=([key]="value3" )
#:declare -A arr=([key]="value" )
#bar:declare -A arr=([key]="value" )
#:declare -A arr=([key]="value" )
#rab:declare -- arr
#:declare -A arr=([key]="value" )
#foobar:bar:declare -A arr=([key]="value2" )
#:declare -A arr=([key]="value" )

associative arrays in the wild

Associative array variable example using array to store document meta name value pairs

declare -A document
...
get-document-meta() {
 local document_meta
 local document_meta_name
 local document_meta_value
 document_meta=$(
  cat ${file} \
  | grep \
  -e '<[!]--\s\+[a-z-]\+:[a-z,]\+\s\+-->' --only-matching \
  | sed -e 's/\(.*\)/\1/' \
  -e 's///g' 
 )
 test ! "${document_meta}" || {
  document_meta_name=$( 
   echo "${document_meta}" | cut -f1 -d:
  )
  document_meta_value=$(
   echo "${document_meta}" | cut -f2 -d:
  )
  document["${document_meta_name}"]="${document_meta_value}" 
 }
}

source: sh2-u2-theme-default/include.sh

to declare a variable to be a reference to another variable

declare -n allows you to declare namerefs in bash. That is, we can use it to a name to be used reference another name.

The -n option adds the nameref attribute to the name provided to the declare command.

Basic usage

#
# declare nameref
#
declare -n VARIABLE 

Nameref variable example

Source

#!/bin/bash
## test-declare-nameref
## version 0.0.1 - initial
##################################################
test-declare-nameref() {
  declare -n X=x
  declare -i x
  echo setting x to 1 ...
  x=1
  echo x: ${x}
  echo X: ${X}
  echo incrementing x 9 times
  _() { x+=1 ; }
  for i in {1..9} ; do _ ; done
  echo x: ${x}
  echo X: ${X}
  echo unsetting X ...
  unset X
  echo x: ${x}
  echo X: ${X}
}
##################################################
if [ ${#} -eq 0 ] 
then
 true
else
 exit 1 # wrong args
fi
##################################################
test-declare-nameref
##################################################
## generated by create-stub2.sh v0.1.2
## on Mon, 22 Jul 2019 20:31:35 +0900
## see <https://github.com/temptemp3/sh2>
##################################################

Commands

bash test-declare-nameref.sh

Ouput

setting x to 1 ...
x: 1
X: 1
incrementing x 9 times
x: 10
X: 10
unsetting X ...
x:
X:

to dump variables

Using declare by itself may be used to dump variable names and functions along with their value and definitions, respectfully.

Declare command example

declare

to test a function

The declare command may be used to test if a function has been declared and is usable within the scope of the bash program.

Function test examples

#
# return name and definition of function if declared
#
declare -f ${function_name} 
#
# returns name only of function if declared
#
declare -F ${function_name} 

to give a variable attributes

Attribute variable example

#
# give variable attribute x
#
declare -X VARIABLE 

to remove variable attributes

Use '+' instead of '-'.

Variable attribute removal example

#
# remove attribute x from variable
#
declare +X VARIABLE 

Attribute removal behavior may vary for array and readonly variables.

to list attributes

List all variables in addition to their attributes.

declare -p in bash

Print variables and attributes in bash using the -p option displays the attributes of the name provided to the declare command. Variables may include an assigned value.

declare -p 

to declare a variable without attributes

declare in bash without attributes

The declare command may be used without specifying attributes resulting in an assignment.

Declare variable example

#
# declare variable without attribute
#
declare VARIABLE[=VALUE] 

equvalent to

#
# declare variable 
#
VARIABLE=[VALUE] 

to declare a readonly variable

declare -r in bash

Declare read-only variable in bash using the -r option adds the read-only attribute to the variable name provided to the declare command such that the variable may not be reassigned.

Read-only variable example

#
# declare readonly
#
declare -r VARIABLE 

to declare a variable to be treated as an integer

declare -i in bash

Declare integer variables in bash using the -i option adds the integer attribute to the variable name provided to the declare command such that the variable is to treated as an integer.

Integer variable example

#
# declare integer
#
declare -i VARIABLE 

See also

to declare a variable to be case-insensitive, or lowercase

declare -l in bash

Declare lowercase variables in bash using the -l option adds the lowercase attribute to the variable name provided to the declare command such that any value is converted to lowercase on assignment.

Lower variable example

#
# declare lower
#
declare -l VARIABLE 

to declare a variable to be uppercase

declare -u in bash

Declare uppercase variables in bash using the -u option adds the uppercase attribute to the variable name provided to the declare command such that any value is converted to uppercase on assignment.

Upper variable example

#
# declare upper
#
declare -u VARIABLE 

to export variables or functions to subshells

declare -x in bash

Export variables and functions in bash using the -x option adds the export attribute to the variable or function name provided to the declare command.

export variable to subshells

Export variable example

#
# declare export variable
#
declare -x VARIABLE 

export function to subshells

Export function example

#
# declare export function
#
declare -xf FUNCTION

commands similar to declare

In addition, to declare, the following commands allow modification of bash variable attributes.

local

Same as declare but with local bindings for functions

See bash using local

typeset

Synonym for declare. That can be used interchangeably. May be used for compatibility with ksh or other POSIX complaint shell; however, set of option available may differ.

unset

Remove variable from list of declared variables. Does not apply to indexed and associative arrays. Can be used on functions. Some options similar to declare, local, and typeset.


questions

Questions and answers regarding declare in bash.

why declare?

Typing. Declare allows you to apply or take away attributes to variables in bash similar to how types or assigned in statically typed programming languages. For example, you may want to make it so a variable may not be reassigned a new value. This can be accomplished using the bash builtin command declare.

declare or typeset?

Either is fine. However, I personally don't use typeset. Although it doesn't hurt to know what it is at least or in case you have to migrate to ksh for some reason.

do I need declare to assign a value to a variable?

No. For most cases, you do not need declare to assign values to a variable. However, there may be side effects of declaring variable attributes after assignment. In that case, it would be advantageous to declare attributes before or on assignment in a single statement assigning value to a variable.

why would I declare a variable without value in bash?

You may declare a variable without value to communicate that a variable may be modified from this point on or to unset a variable via assignment.

It is not necessary to declare a variable for the purpose of initialization if no assignment was made prior to appearance in script.


© Nicholas Shellabarger