Exit code of variable assignment to command substitution in Bash
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$?
.
Exit code of command substitution in bash local variable assignment
If you look at the man file for local
(which is actually just the BASH builtins man page), it is treated as its own command, which gives an exit code of 0
upon successfully creating the local variable. So local
is overwriting the last-executed error code.
Try this:
function testing { local test; test="$(return 1)"; echo $?; }; testing
EDIT: I went ahead and tried it for you, and it works.
Exit code of variable assignment to command substitution in Bash
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$?
.
Local variable assignment with command substitution behaves unexpectedly
Not only local
, all declaration utilities mask the exit code of the substituted command, because the assignment does not fail.
The usual workaround is:
local _ui_envname
_ui_envname=$(dialog --stdout --cancel-label "Back" --inputbox 'Enter the new environment name:' 0 0) || { echo "Failed"; exit 1; }
Will variable be assigned to empty if the command for command substitution failed in shell scriping?
No, it's not because the command failed that a
is empty.
The command didn't produce any output data, so there is no data to be captured in a
.
Revise the function to read:
f(){ echo Hello; return 1; }
Now run the command substitution. You'll find that a
contains Hello
. If you check $?
immediately after the assignment, it contains 1
, the status returned from the function. Exit statuses and command outputs are separate.
The documentation is in the GNU Bash manual for Command Substitution.
Can the exit code of a subshell be captured when declaring a variable with process substitution?
To check the status of the process substitution, the assignment must be the only thing performed by the statement. In a statement such as local x=$(false)
, the value returned is the status of local, which typically succeeds. To create a local readonly variable in a function and check the assignment from a process substitution, you can do:
local x
x=$(false) || echo "assigment of x failed !!" >&2
readonly x
getting the error code of a sub-command using $(...)
Use process substitution
instead of command substitution + here string
:
read X < <(grep 'hello' hello.txt)
This will get you 1
when using echo $?
.
PS: If grep
fails it will write an error on your terminal.
If you want to suppress error then use:
read X < <(grep 'hello' hello.txt 2>/dev/null)
Command Substitution does not execute unless i echo it
As GordonDavisson pointed out, removing the return statement and just printing it as an array did the job.
The function will return the printed value and i can parse that in the main program.
Related Topics
How to Detect Invalid Utf8 Unicode/Binary in a Text File
How to Shutdown a Spring Boot Application in a Correct Way
What Killed My Process and Why
How Do the Likely/Unlikely Macros in the Linux Kernel Work and What Is Their Benefit
How to Set the Environmental Variable Ld_Library_Path in Linux
How to 'Grep' a Continuous Stream
How to Concatenate Multiple Lines of Output to One Line
Change the X-Frame-Options to Allow All Domains
Remove a Specific Character Using Awk or Sed
How to Get Cron to Call in the Correct Paths
How to Change the Output Color of Echo in Linux
How to Send a File as an Email Attachment Using Linux Command Line
Format and Then Convert Txt to CSV Using Shell Script and Awk
Does Malloc Lazily Create the Backing Pages For an Allocation on Linux (And Other Platforms)
Shell/Bash Shortcut For Bulk Renaming of Files in a Folder
How to Get the Bssid of Currently Connected Network Through Bash