Exit code of variable assignment to command substitution in Bash

bash, exit-code, linux, shell

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

Problem

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!

Original source