16

What's the difference between :- and := in Bash parameter substitution?

They seem to both set the default?

moodymudskipper
  • 46,417
  • 11
  • 121
  • 167
Casebash
  • 114,675
  • 90
  • 247
  • 350
  • 3
    The practical difference is `Positional parameters and special parameters may not be assigned` using `:=`. (they can with `:-`) – David C. Rankin Jan 12 '18 at 02:41

3 Answers3

15

Quoting Bash Reference Manual:

${parameter:-word}

If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.

${parameter:=word}

If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substituted. Positional parameters and special parameters may not be assigned to in this way.

The difference is that := doesn't only substitute the word, it also assigns it to the parameter:

var=
echo "$var"               # prints nothing
echo "${var:-foo}"        # prints "foo"
echo "$var"               # $var is still empty, prints nothing
echo "${var:=foo}"        # prints "foo", assigns "foo" to $var
echo "$var"               # prints "foo"

See this great wiki.bash-hackers.org tutorial for more information.

PesaThe
  • 7,259
  • 1
  • 19
  • 43
  • How is `"${var:=foo}"` different from `"${var=foo}"` then? – sheerun Mar 05 '20 at 22:38
  • 1
    @sheerun From [Bash Reference Manual](https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html): `If the colon is included, the operator tests for both parameter’s existence and that its value is not null; if the colon is omitted, the operator tests only for existence.` – PesaThe Mar 06 '20 at 09:08
2
$ var=
$ echo $(( ${var:-1} + 3 ))  # local substitution if value is null
4
$ echo $(( ${var} + 3 ))
3

# set it to null 
$ var= 
$ echo $(( ${var:=1} + 3 )) # global substitution if value is null
4
$ echo $(( ${var} + 3 ))
4 

https://www.tldp.org/LDP/abs/html/parameter-substitution.html

iamauser
  • 11,119
  • 5
  • 34
  • 52
2

From https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html :

${parameter:-word}
If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.

${parameter:=word}
If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substituted. Positional parameters and special parameters may not be assigned to in this way.

In :- does not modify the parameter value, just 'prints' the expansion of word. In := the parameter gets the new value that is the expansion of word and also it 'print' the expansion of word.
Sometimes in scripts you want to assign a default value to a variable if it was not set. Many use VAR=${VAR:-1}, which will assign '1' to VAR if VAR was not set. This may be also written as : ${VAR:=1}, which will assign '1' to VAR if VAR was not set and run : $VAR or : 1, but : is a special builtin in bash and will discard all arguments and do nothing.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111