InterLinked
InterLinked

Reputation: 1403

Properly nesting conditionals in if statements

I had a set of conditionals working perfectly. However, I needed to tweak the algorithm (making it more complicated), which involved nested conditionals in bash.

For instance, here is one such block:

a1=C
a2=P
a3=E
a4=1
a5=7
a6=0
a7=4
a8=T
a9=K
a10=S
letters=$(echo {A..Z} | tr -d ' ')
if [ "$c3" != "$a3" ]
    then
        c3=${letters:$((RANDOM%26+1)):1}
        if [ "$c3" == "$a3" ] && (( $count % $difficulty3 != 0 ))
        then
            c3=${letters:$((RANDOM%26+1)):1}
            if [ "$c3" == "$a3" ] && [ [ "$c1" != "$a1" ] || [ "$c2" != "$a2" ] ]
            then
                c3=${letters:$((RANDOM%26+1)):1}
            fi
        fi
    fi

The innermost if statement essentially checks, if c3 and a3 are equal, to make sure that c1 and a1 are also equal and that c2 and a2 are also equal. If not, it reassigns the variable c3 once more.

My thought is to do an if (true AND ( true OR true)) type logic, but this doesn't seem to work here. I get:

line 367: [: too many arguments

All the c and a variables are a single letter or numerical digit, so strings with spaces as I've seen in related SO posts on this subject are not causing the issue.

When I try doing double brackets instead of single around the whole thing, the script fails to run at all. Parentheses won't work since these aren't arithmetic operations... so I'm scratching my head now. It seems this is the proper way to do nested conditionals... what am I missing?

Upvotes: 1

Views: 72

Answers (1)

John Kugelman
John Kugelman

Reputation: 361585

Square brackets look like special shell syntax but they're not at all. [ is just another name for test, and the closing ] is merely an argument that's ignored.

You can use curly braces, which are special syntax:

if [ "$c3" == "$a3" ] && { [ "$c1" != "$a1" ] || [ "$c2" != "$a2" ]; }

Parentheses also work. The extra ; isn't needed, but they create an unnecessary sub-shell, so I recommend curly braces:

if [ "$c3" == "$a3" ] && ( [ "$c1" != "$a1" ] || [ "$c2" != "$a2" ] )

Upvotes: 4

Related Questions