Search code examples
bashreturn

Bash check return code of a command inline


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.


Solution

  • 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.