linuxbashshellexit-code

Exit code of variable assignment to command substitution in Bash


I am confused about what error code the command will return when executing a variable assignment plainly and with command substitution:

a=$(false); echo $?

It outputs 1, which let me think that variable assignment doesn't sweep or produce new error code upon the last one. But when I tried this:

false; a=""; echo $?

It outputs 0, obviously this is what a="" returns and it override 1 returned by false.

I want to know why this happens, is there any particularity in variable assignment that differs from other normal commands? Or just be cause a=$(false) is considered to be a single command and only command substitution part make sense?

-- UPDATE --

Thanks everyone, from the answers and comments I got the point "When you assign a variable using command substitution, the exit status is the status of the command." (by @Barmar), this explanation is excellently clear and easy to understand, but speak doesn't precise enough for programmers, I want to see the reference of this point from authorities such as TLDP or GNU man page, please help me find it out, thanks again!


Solution

  • Upon executing a command as $(command) allows the output of the command to replace itself.

    When you say:

    a=$(false)             # false fails; the output of false is stored in the variable a
    

    the output produced by the command false is stored in the variable a. Moreover, the exit code is the same as produced by the command. help false would tell:

    false: false
        Return an unsuccessful result.
        
        Exit Status:
        Always fails.
    

    On the other hand, saying:

    $ false                # Exit code: 1
    $ a=""                 # Exit code: 0
    $ echo $?              # Prints 0
    

    causes the exit code for the assignment to a to be returned which is 0.


    EDIT:

    Quoting from the manual:

    If one of the expansions contained a command substitution, the exit status of the command is the exit status of the last command substitution performed.

    Quoting from BASHFAQ/002:

    How can I store the return value and/or output of a command in a variable?

    ...

    output=$(command)

    status=$?

    The assignment to output has no effect on command's exit status, which is still in $?.

    This is not bash-specific. Quoting the end of section 2.9.1 "Simple Commands" in the "Shell & Utilities" volume of the The Open Group Base Specifications Issue 7, POSIX.1-2017 :

    If there is no command name, but the command contained a command substitution, the command shall complete with the exit status of the last command substitution performed