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!
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 oncommand
'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