38

In bash scripting:

we create variable by just naming it:

abc=ok

or we can use declare

declare abc=ok

what's the difference?

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

  • 5
    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 '16 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 '16 at 10:14
29

From help -m declare:

NAME

    declare - Set variable values and attributes.

SYNOPSIS

    declare [-aAfFgilnrtux] [-p] [name[=value] ...]

DESCRIPTION

    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:

      -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)
      -g
        create global variables when used in a shell function; otherwise ignored
      -p
        display the attributes and value of each NAME

    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
      -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.

SEE ALSO

    bash(1)

IMPLEMENTATION

    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
ok
$ abc=not-ok
bash: abc: readonly variable


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

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 '16 at 12:48
  • Great! I love examples, best way to teach/learn. Thanks! – turkenh Aug 4 '17 at 9:02
  • 1
    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 '18 at 5:04
11

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'
f
echo "After f: a is $a"
echo "After f: b is $b"

Output:

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 synonym, local. 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 '16 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 at 11:42
  • 1
    @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. – Gilles Apr 14 at 18:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.