3

Ok, so this is killing me, it might sound like a simple question, but I cannot get it to work Im trying to check a command return code without storing it on a variable and simple cant.

[ $(true) ] && echo Worked
[[ $(true) ]] && echo Worked

[ $(true) -eq 0 ] && echo Worked
[[ $(true) -eq 0 ]] && echo Worked

[ "$(true)" -eq "0" ] && echo Worked
[[ "$(true)" -eq "0" ]] && echo Worked

[ $(true) -eq '0' ] && echo Worked
[[ $(true) -eq '0' ]] && echo Worked

Well, I tried pretty much every single combination, with quotes on one side, both sides, the left side, the right side... Some of them will actually output Worked but they are not actually checking the return code, if you test them with false they will also "Worked"

My final code is to run 5 commands and get the first that works, and the idea is to put them on a if/elseif statement, but I really don't want to put every single command on a variable and then check the variable, its annoying.

5
  • 1
    true && echo worked gives worked, false && echo worked gives no echo ... Commented Jul 18, 2022 at 4:13
  • 3
    You're confusing the output of a command (i.e. what it prints) with its exit status (i.e. whether it succeeds or fails). $( ) gets its output, not its exit status. [ ] and [[ ]] do tests on strings and numbers, not exit statuses. Things like if and && and || test exit statuses directly, so just use command && echo Worked. See my answer to a similar question here. Commented Jul 18, 2022 at 4:24
  • @GordonDavisson Thank you very much for that, Never crossed my mind to test without bracket but your explanation clarify everything, if you want, post it as answer !!! Commented Jul 18, 2022 at 4:42
  • @Claudio you are absolutely right as well, appreciate your help !!! Commented Jul 18, 2022 at 4:51
  • Are you looking for: cmd1 || cmd2 || cmd3 || cmd4 || cmd5 && echo 'one command succeeded'? This tries each command until one succeeds. If a command succeeds, no further commands in the OR list are executed (it skips to echo). If none succeed, echo doesn't execute. Commented Jul 18, 2022 at 5:11

1 Answer 1

4

The single bracket [ or double one [[ are not needed to check a commands return code.

Yes the single one [ is for checking numeric or string values with special operators:

[ 1 -eq 1 ] && echo worked
worked

[ "1" -eq "1" ] && echo worked
worked

[ 1 -eq 2 ] && echo worked # nothing

[ "1" -eq "2" ] && echo worked # nothing

And the double is the same but with different operators :

[[ 1 == 1 ]] && echo worked
worked

[[ "1" == "1" ]] && echo worked
worked

[[ 1 == 2 ]] && echo worked # nothing

[[ "1" == "2" ]] && echo worked # nothing

But for checking a command return value we do not need to wrap the command inside single or double brackets

# file.txt exists 
ls file.txt  > /dev/null 2>&1 && echo worked
worded

# file.json does not exist
ls file.json > /dev/null 2>&1 && echo worked # nothing

It is true for if / else statement

# not needed
# if [ ls file.txt > /dev/null 2>&1 ]; then

# or
# if [[ ls file.txt > /dev/null 2>&1 ]]; then


if ls file.txt > /dev/null 2>&1 ; then
    echo found
else
    echo file not found
fi

NOTE
For not making it complicated I did not mention all the differences between single bracket [ and double one [[
Please refer to What is the difference between test, [ and [[ ? for more information
And thanks Gordon Davisson for commenting and reminding me this.

Sign up to request clarification or add additional context in comments.

2 Comments

This explanation of the difference between [ ] and [[ ]] isn't quite right. They do have some different operators, but both use -eq for numeric comparison, and = for string comparison (e.g. [ 1 -eq 01 ] evaluates as true, and [ 1 = 01 ] as false). Bash accepts == as a synonym for = in both, but not all other shells do (and if you're specifically using bash, [[ ]] has much cleaner syntax so you should just use that). See BashFAQ #31: "What is the difference between test, [ and [[ ?"
@GordonDavisson thanks for the comment, yes you are right and I knew there are other differences, but did not want to make it complicated for him. I will update the answer, adding a note about what you mentioned, and please feel free to modify the answer. I appreciate if a senior one helps me learning bash correctly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.