2023-07-05 10:53:12 +02:00
# The declare builtin command
## Synopsis
declare [-aAfFgilnrtux] [-p] [NAME[=VALUE] ...]
# obsolete typeset synonym
typeset [-aAfFgilnrtux] [-p] [NAME[=VALUE] ...]
## Description
`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.
2024-03-30 20:09:26 +01:00
Don't use it's synonym `typeset` when coding for Bash, since it's
2023-07-05 10:53:12 +02:00
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
2024-10-08 06:00:17 +02:00
`[-+]c` **Undocumented** convert NAMEs to "capcase" on assignment (makes the first letter upper-case and the rest lower). Requires Bash built with `-DCASEMOD_CAPCASE`
2023-07-05 10:53:12 +02:00
`-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)
2024-10-08 06:00:17 +02:00
`[-+]i` make NAMEs have the "integer" attribute
2023-07-05 10:53:12 +02:00
`[-+]l` convert NAMEs to lower case on assignment (makes sure the variable contains only lower case letters)
2024-10-08 06:00:17 +02:00
`[-+]n` make NAME a reference to the variable named by its value. Introduced in Bash 4.3-alpha.
''`${!NAME}`'' reveals the reference variable name, VALUE.
Use `unset -n NAME` to unset the variable. (`unset -v NAME` unsets the VALUE variable.)
2024-03-30 19:22:45 +01:00
Use `[[ -R NAME ]]` to test if NAME has been set to a VALUE, another variable's name.
2023-07-05 10:53:12 +02:00
`-p` display the attributes and value of each NAME
`[-+]r` make NAMEs readonly (removing with `+r` is valid syntax, but not possible)
2024-10-08 06:00:17 +02:00
`[-+]t` make NAMEs have the "trace" attribute (effective only for functions)
2023-07-05 10:53:12 +02:00
`[-+]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=(...)`)
2024-10-08 06:00:17 +02:00
!= 0 attempt to use `+a` to "destroy" an array
2023-07-05 10:53:12 +02:00
!= 0 attemt to display a non-existent function with `-f`
## Notes
Unix shells offer very few datatypes. Bash and some other shells extend
2024-10-08 06:00:17 +02:00
this by allowing "attributes" to be set on variable names. The only
2023-07-05 10:53:12 +02:00
attributes specified by POSIX are `export` and `readonly` , which are set
by their own dedicated builtins. Datatypes in bash have a few other
interesting capabilities such as the ability to modify data on
assignment.
## Examples
### Display defined functions
2024-10-08 06:00:17 +02:00
`declare -f` can be used to display all defined functions...
2023-07-05 10:53:12 +02:00
$ declare -f
2024-10-08 06:00:17 +02:00
foo ()
{
2023-07-05 10:53:12 +02:00
echo "FOO is BAR"
}
2024-10-08 06:00:17 +02:00
world ()
{
2023-07-05 10:53:12 +02:00
echo "Hello World!"
}
2024-10-08 06:00:17 +02:00
...or just a specific defined function.
2023-07-05 10:53:12 +02:00
$ declare -f foo
2024-10-08 06:00:17 +02:00
foo ()
{
2023-07-05 10:53:12 +02:00
echo "FOO is BAR"
}
### Nameref
Bash 4.3 adds a new way to indirectly reference variables. `typeset -n`
or `declare -n` can be used to make a variable indirectly refer to
another. In Bash, the lvalue of the assignment given to `typeset -n` or
`declare -n` will refer to the variable whose name is expanded on the
RHS.
`typeset -n` is used in the example below. See notes below.
# Sum a set of arrays and assign the result indirectly, also printing each intermediary result (without portability workarounds)
# sum name arrname [ arrname ... ]
function sum {
typeset -n _result=$1 _arr
typeset IFS=+
_result=0
for _arr in "${@:2}"; do # Demonstrate the special property of "for" on a nameref.
(( _result += ${_arr[*]} ))
printf '%s = %d\n' "${!_result}" "$_result" # Demonstrate the special property of ${!ref} on a nameref.
done
}
a=(1 2 3) b=(6 5 4) c=(2 4 6)
sum total a b c
printf 'Final value of "total" is: %d\n' "$total"
2024-04-01 06:10:32 +02:00
< div hide > function sum {
2023-07-05 10:53:12 +02:00
typeset -n _result=$1
shift
typeset IFS=+ _arrx
_result=0
for _arrx in "$@"; do # Demonstrate the special property of "for" on a nameref.
typeset -n _arr=$_arrx
(( _result += ${_arr[*]} ))
printf '%s = %d\n' "${!_result}" "$_result" # Demonstrate the special property of ${!ref} on a nameref.
done
}
a=(1 2 3); b=(6 5 4); c=(2 4 6) sum total a b c printf \'Final value of
2024-04-01 06:10:32 +02:00
\"total\" is: %d\\n\' \"\$total\" </ div >
2023-07-05 10:53:12 +02:00
`typeset -n` is currently implemented in ksh93, mksh, and Bash 4.3. Bash
2024-03-30 19:22:45 +01:00
and mksh's implementations are quite similar, but much different from
ksh93's. See [Portability considerations ](#portability_considerations )
for details. ksh93 namerefs are much more powerful than Bash's.
2023-07-05 10:53:12 +02:00
## Portability considerations
- `declare` is not specified by POSIX(r)
- `declare` is unique to Bash and totally non-portable with the
possible exception of Zsh in Bash compatibility mode. Bash marks the
synonym `typeset` as obsolete, which in Bash behaves identically to
`declare` . All other Korn-like shells use `typeset` , so it probably
2024-03-30 20:09:26 +01:00
isn't going away any time soon. Unfortunately, being a non-standard
2023-07-05 10:53:12 +02:00
builtin, `typeset` differs significantly between shells. ksh93 also
considers `typeset` a special builtin, while Bash does not - even in
POSIX mode. If you use `typeset` , you should attempt to only use it
in portable ways.
2024-10-08 06:00:17 +02:00
- **todo** nameref portability...
2023-07-05 10:53:12 +02:00
## See also
2024-01-29 02:07:56 +01:00
- [arrays ](../../syntax/arrays.md )
- [readonly ](../../commands/builtin/readonly.md )
- [unset ](../../commands/builtin/unset.md )
2023-07-05 10:53:12 +02:00
- [declaration commands ](http://austingroupbugs.net/view.php?id=351 )
will change the behavior of certain builtins such as `export` in the
next version of POSIX.