This is an old revision of the document!


The declare builtin command

declare [-aAfFgilrtux] [-p] [NAME[=VALUE] ...]

# obsolete typeset synonym
typeset [-aAfFgilrtux] [-p] [NAME[=VALUE] ...]

declare is used to display or set variables along with variable attributes. When used to display variables/functions and their value, the output is re-usable as input for the shell.

If no NAME is given, it displays the values of all variables or functions when restricted by the -f option.

If NAME is followed by =VALUE, declare also sets the value for a variable.

When used in a function, declare makes NAMEs local variables, unless used with the -g option.

Don't use it's synonym typeset when coding for Bash, since it's tagged as obsolete.

Options

Below, [-+]X indicates an attribute, use -X to set the attribute, +X to remove it.

Option Description
[-+]a make NAMEs indexed arrays (removing with +a is valid syntax, but leads to an error message)
[-+]A make NAMEs associative arrays
-f restrict action or display to function names and definitions (removing with +f is valid syntax, but leads to an error message)
-F restrict display to function names only (plus line number and source file when debugging)
-g create global variables when used in a shell function; otherwise ignored (by default, declare declares local scope variables when used in shell functions)
[-+]i make NAMEs have the "integer" attribute
[-+]l convert NAMEs to lower case on assignment (makes sure the variable contains only lower case letters)
-p display the attributes and value of each NAME
[-+]r make NAMEs readonly (removing with +r is valid syntax, but not possible)
[-+]t make NAMEs have the "trace" attribute (effective only for functions)
[-+]u convert NAMEs to upper case on assignment (makes sure the variable contains only upper case letters)
[-+]x make NAMEs exported

Return status

Status Reason
0 no error
!= 0 invalid option
!= 0 invalid variable name given
!= 0 attempt to define a function using -f
!= 0 assignment to a readonly variable
!= 0 removing the readonly-attribute from a readonly variable
!= 0 assignment to an array variable without the compound assignment syntax (array=(…))
!= 0 attempt to use +a to "destroy" an array
!= 0 attemt to display a non-existent function with -f

Unix shells offer very few datatypes. POSIX® specifies only one, strings. Bash and some other shells extend this in an unusual way by allowing "attributes" which represent datatypes to be associated with variable names. Bash can effectively set these attributes in several ways: declare; local; the compound assignment syntax; and the function definition syntax. For instance, in that sense one way to think about functions is as string variables with the function attribute set, that contain bash code which can only be assigned using a funky syntax and dereferenced in a particular way. You can even export them (though many shells don't automatically inherit functions from the environment like Bash does.) Datatypes in bash have a few other interesting and unusual capabilities such as the ability to modify data on assignment.

The ksh88 manpage mentions that arithmetic performed on variables explicitly declared with the integer attribute outperforms that of ordinary string variables. I have not tested this or found it mentioned elsewhere, but it's something to keep in mind. Polymorphic datatypes used in dynamic programming languages such as Bash do suffer some additional overhead when type checking must occur, and depending on the way the shell is implemented, setting the type on variables that will only ever contain integers can move that check from the time it's used to the time it's assigned, reducing that overhead in some cases.

It can also improve code safety to guarantee that certain variables will only contain certain types by treating them as you would in a statically typed language. This is considered good practice in many langauges. A somewhat recent trend is to offer a choice of typing in languages which were previously either strictly static or strictly dynamic. C# is one example. Bash has had this ability for a couple decades. 8-)

Display defined functions

declare -f can be used to display all defined functions…

$ declare -f
foo () 
{ 
    echo "FOO is BAR"
}
world () 
{ 
    echo "Hello World!"
}
…or just a specific defined function.
$ declare -f foo
foo () 
{ 
    echo "FOO is BAR"
}

  • declare is not specified by POSIX®
  • declare is unique to Bash and totally non-portable with the possible exception of Zsh with Bash compatibility. Though the documentation marks the synonym typeset as obsolete, AFAICT this isn't fully justified. All other Korn-like shells use typeset, so it probably isn't going away any time soon. Unfortunately, being a non-standard builtin, not all shared features have compatible option flags even though Bash's available typeset features are almost a proper subset of ksh's. Bash of course lacks all floating-point related options. Additionally, Bash arrays must be homogeneous datatypes whereas ksh93 compound variables are not necessarily, which means declare cannot be used to set the type of an individual element or used within the compound-assignment syntax. For example, declare -ia creates an indexed array whose elements have the integer attribute. In both shells, typeset creates locally scoped variables when used within a function, however, ksh lacks a local builtin, and has no equivalent to the -g option for overriding this behavior.
You could leave a comment if you were logged in.