Search code examples
bashenvironment-variablesvariable-expansion

Equal/minus sign without a colon in a parameter expasion in bash


I found a snippet like this in a Bash script recently:

$ echo ${A=3}

Now, I know that ${A:=3} would set the variable A if A is "falsy", or ${A:-3} would return 3 if A is "falsy." I have never seen these similar expressions without the colon though, and I cannot find the explanation for these colon-less expressions in the Bash's documentation.

What is going on here?


Solution

  • Actually, the documentation does explain what is going on here, even if burying the lede a bit:

    When not performing substring expansion, using the form described below (e.g., ‘:-’), Bash tests for a parameter that is unset or null. Omitting the colon results in a test only for a parameter that is unset. Put another way, if the colon is included, the operator tests for both parameters’ existence and that its value is not null; if the colon is omitted, the operator tests only for existence.

    In practice, this means that they behave the same way if the variables are unset:

    $ echo ${A=no-colon}
    no-colon
    $ echo ${B:=with-colon}
    with-colon
    $ echo $A
    no-colon
    $ echo $B
    with-colon
    

    However, if the variables are set to the empty string, then the behavior is different. The expression with a colon will set the variable and return the value, and the one without will leave the variable as is (i.e., set to the empty string) and return its empty value:

    $ A='' ; B=''
    $ echo ${A=no-colon}
    
    $ echo ${B:=with-colon}
    with-colon
    $ echo $A
    
    $ echo $B
    with-colon
    

    As stated in the documentation, the same behavior applies to the other "operators" (-, ?, +).

    Posting it in the spirit of Can I answer my own question? and because it took a surprisingly long time for me to learn it, even after finding it in code. Maybe making it a bit more explicit, with some examples, can help somebody else out there :)