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!
All of the Bash builtins return an exit status of zero if they succeed and a non-zero status on failure, so they may be used by the conditional and list constructs. All builtins return an exit status of 2 to indicate incorrect usage, generally invalid options or missing arguments.
To set an exit code in a script use exit 0 where 0 is the number you want to return. In the following example a shell script exits with a 1 . This file is saved as exit.sh . Executing this script shows that the exit code is correctly set.
The dollar sign before the thing in parenthesis usually refers to a variable. This means that this command is either passing an argument to that variable from a bash script or is getting the value of that variable for something.
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$?
.
Note that this isn't the case when combined with local
, as in local variable="$(command)"
. That form will exit successfully even if command
failed.
Take this Bash script for example:
#!/bin/bash function funWithLocalAndAssignmentTogether() { local output="$(echo "Doing some stuff.";exit 1)" local exitCode=$? echo "output: $output" echo "exitCode: $exitCode" } function funWithLocalAndAssignmentSeparate() { local output output="$(echo "Doing some stuff.";exit 1)" local exitCode=$? echo "output: $output" echo "exitCode: $exitCode" } funWithLocalAndAssignmentTogether funWithLocalAndAssignmentSeparate
Here is the output of this:
nick.parry@nparry-laptop1:~$ ./tmp.sh output: Doing some stuff. exitCode: 0 output: Doing some stuff. exitCode: 1
This is because local
is actually a builtin command, and a command like local variable="$(command)"
calls local
after substituting the output of command
. So you get the exit status from local
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With