In bash scripting:

we create variable by just naming it:


or we can use declare

declare abc=ok

what's the difference?

and why does bash make so many ways to create a variable?

  • 6
    When used in a function, declare makes NAMEs local, as with the local command. The -g option suppresses this behavior. See help declare.
    – Cyrus
    Jan 10, 2016 at 8:22
  • 2
    declare makes it possible to create associative arrays, integers, and read-only variables. Also, it expands its arguments, so things like declare $name=1 are possible.
    – choroba
    Jan 10, 2016 at 10:14

2 Answers 2


From help -m declare:


    declare - Set variable values and attributes.


    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.


        restrict action or display to function names and definitions
        restrict display to function names only (plus line number and source file when debugging)
        create global variables when used in a shell function; otherwise ignored
        display the attributes and value of each NAME

    Options which set attributes:

        to make NAMEs indexed arrays (if supported)
        to make NAMEs associative arrays (if supported)
        to make NAMEs have the ‘integer’ attribute
        to convert NAMEs to lower case on assignment
        make NAME a reference to the variable named by its value
        to make NAMEs readonly
        to make NAMEs have the ‘trace’ attribute
        to convert NAMEs to upper case on assignment
        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.




    GNU bash, version 4.3.11(1)-release (i686-pc-linux-gnu)
    Copyright (C) 2013 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

So, declare is used for setting variable values and attributes.

Let me show the use of two attributes with a very simple example:

$ # First Example:
$ declare -r abc=ok
$ echo $abc
$ abc=not-ok
bash: abc: readonly variable

$ # Second Example:
$ declare -i x=10
$ echo $x
$ x=ok
$ echo $x
$ x=15
$ echo $x
$ x=15+5
$ echo $x

From the above example, I think you should understand the usage of declare variable over normal variable! This type of declareation is useful in functions, loops with scripting.

Also visit Typing variables: declare or typeset

  • yes, the "and attributes" is the point! this is the difference.
    – lovespring
    Jan 11, 2016 at 12:48
  • Great! I love examples, best way to teach/learn. Thanks!
    – turkenh
    Aug 4, 2017 at 9:02
  • 2
    You need to know what "attributes" are to understand this answer. They're properties of the variable like 'integer', 'array', or 'readonly'.
    – Noumenon
    May 17, 2018 at 5:04
  • 1
    This does a nice job of explaining declare, but completely ignores what happens when you simply declare a variable through bash.
    – Cheetaiean
    Jan 14, 2020 at 23:41

abc=ok assigns a value to the variable abc. declare abc declares a variable called abc. The two can be combined as declare abc=ok.

In bash, like other shells, string and array variables don't need to be declared, so declare isn't necessary unless you want to pass options, e.g. declare -A abc to make abc an associative array or declare -r to make a variable read-only. However, inside a function, declare does make a difference: it causes the variable to be local to the function, meaning that the value of the variable outside the function (if any) is preserved. (Unless you use declare -g, which makes the variable not local; this is useful when combined with other options, e.g. declare -gA to create a global associative array in a function.) Example:

f () {
  declare a
  a='a in f'
  b='b in f'
  echo "From f: a is $a"
  echo "From f: b is $b"
a='Initial a'
b='Initial b'
echo "After f: a is $a"
echo "After f: b is $b"


From f: a is a in f
From f: b is b in f
After f: a is Initial a
After f: b is b in f

Another thing you can do with the declare builtin is

The declare builtin is unique to bash. It's strongly inspired and very close to ksh's typeset builtin, and bash provides typeset as a synonym of declare for compatibility. (I don't know why bash didn't just call it typeset). There's a third similar one, local, which is otherwise the same but works only within a function. There's also export, which is the same as declare -x, again for compatibility (with every Bourne-style shell).

  • yes! the 'and option' is the point. p.s. if i design the bash, I will let the behavior of "declare" do some thing in different condiftion. this make things simple.
    – lovespring
    Jan 11, 2016 at 12:51
  • Nice answer. A further question, which one amongst export, local and declare is the most compatible with other shells?
    – 0xc0de
    Apr 14, 2019 at 11:42
  • 3
    @0xc0de export exists in all variants of sh. local exists only in bash and zsh, declare only in bash. typeset exists in ksh, bash and zsh. Apr 14, 2019 at 18:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .