austinmarton
austinmarton

Reputation: 2368

Use result of bash comparison in another comparison

I'd like to use the result of a comparison in a subsequent comparison. I'm trying to do something like:

# $1 - expected result
# $2 - actual result
function print_result() {
    if [[ [[ $1 -eq 0 ]] -eq [[ $2 -eq 0 ]] ]]; then  # invalid
        echo "Pass"
    else
        echo "Fail"
    fi
}

I can get the desired behaviour with the more verbose form:

function print_result() {
    if [[ (($1 -eq 0) && ($2 -eq 0)) || (($1 -ne 0) && ($2 -ne 0)) ]]; then 
        echo "Pass"
    else
        echo "Fail"
    fi
}

but it seems like there should be a simpler way?

Upvotes: 4

Views: 90

Answers (2)

rici
rici

Reputation: 241721

You need something which produces the result of the comparison operator as text rather than as a status return. That would be arithmetic expansion: $((expression)).

Note also that bash includes a numeric conditional compound statement -- (( expr )) -- which is often easier to use for numerical comparisons than the non-numerical [[ ... ]] conditional compound statement.

Putting that together, what you are looking for is:

if (( $(($1==0)) == $(($2==0)) )); then

Or just:

if (( ($1==0) == ($2==0) )); then

If you only want to know if $1 and $2 are both zero or both non-zero, then you can use the fact that boolean not (!) always evaluates to either 0 or 1. Consequently, the following even simpler expression is equivalent (but see warning below):

if ((!$1 == !$2)); then 

Important: If you use that in a script, it will work fine, but at the command prompt you need to put a space after the ! to avoid it being interpreted as a history expansion character (unless you've turned history expansion off: if you don't actually use history expansion, turning it off is not a bad idea.)

Upvotes: 2

DanielGibbs
DanielGibbs

Reputation: 10191

A possibly slightly more readable (but not particularly simpler) way would be to store the result of each comparison in a variable and then compare the variables:

function print_result() {
    [[ $1 -eq 0 ]]; arg_one_is_zero=$?
    [[ $2 -eq 0 ]]; arg_two_is_zero=$?
    if [[ $arg_one_is_zero -eq $arg_two_is_zero ]]; then
        echo "Pass"
    else
        echo "Fail"
    fi
}

There might be a better way to store the logical result (exit code) of a comparison in a variable but I couldn't find one after a quick look.

Upvotes: 1

Related Questions