Jinro9
Jinro9

Reputation: 67

Comparing two variables in while loop BASH

I am trying to compare two variable in bash in nested while loops and I am having issues with:

[: 1, : integer expression expected.

My code:

#!/bin/bash

a="10",b="5"
i="1", j="1"
while [ $i -ne $a ]
do
        while [ $j -ne $b ]
        do
                echo"In Child Loop $j Times"
                ((j++))
        done
        j="1"
        echo"In Parent Loop $i Times"
        ((i++))
done

Upvotes: 5

Views: 20424

Answers (3)

striving_coder
striving_coder

Reputation: 798

You shouldn't do two string assignments separates with commas, since "," is added to the value of first variable. For example:

a="10", b="5"
echo $a
> 10,

Instead, do each assignment on its own line:

a="10"
b="5"
i="1"
j="1"

Alternatively, you can remove commas in your initialization lines:

a=10 b=5
i=1 j=1

Upvotes: 1

Henk Langeveld
Henk Langeveld

Reputation: 8456

You can combine multiple assignments, separated by whitespace only. Just replace the commas with spaces:

a="10" b="5"
i="1" j="1"

Or even:

a="10" b="5" i="1" j="1"

You can also remove quotes and reduce clutter:

a=10 b=5 i=1 j=1

But caution is advised here. Keep things readable.


The shell has a rule for dealing with assignments prefixing commands. For an external command, that command will run with the assigned variables in its own environment.

For an internal command, the assignment(s) will be permanent for the current process, so the variables and their values will persist after the command completes.

Upvotes: 1

David C. Rankin
David C. Rankin

Reputation: 84642

You have 2 primary issues. (1) you forgot to leave a space between echo and the start of the string, and (2) as pointed out, a comma is not a valid end of line specifier in bash. Bash uses a semi-colon as the end of line specifier. Meaning if you want to put 2 assignments on the same line, you must put a ; between them, not a ,. With the changes your code is:

#!/bin/bash

a="10"
b="5"
i="1"
j="1"

while [ $i -ne $a ]
do
    while [ $j -ne $b ]
    do
        echo "In Child Loop $j Times"
        ((j++))
    done
    j="1"
    echo "In Parent Loop $i Times"
    ((i++))
done

output:

$ bash nestedtest.sh
In Child Loop 1 Times
In Child Loop 2 Times
In Child Loop 3 Times
In Child Loop 4 Times
In Parent Loop 1 Times
In Child Loop 1 Times
In Child Loop 2 Times
In Child Loop 3 Times
In Child Loop 4 Times
In Parent Loop 2 Times
In Child Loop 1 Times
In Child Loop 2 Times
In Child Loop 3 Times
In Child Loop 4 Times
In Parent Loop 3 Times
In Child Loop 1 Times
In Child Loop 2 Times
In Child Loop 3 Times
In Child Loop 4 Times
In Parent Loop 4 Times
(snip)

Additionally, since bash does not have typed variables, there can be ambiguity whether a variable should be treated as a number or as a string. Type is determined by context. However, you can let bash know how you intend to use a variable if you declare the variable before its first use. E.g.:

declare -i a="10" b="5" i="1" j="1"

NOTE: here you can place more than one declaration on a single line simply separate by a space.

Additionally, if you receive an "[: 1, : integer expression expected" error. that is usually due to one of two reasons. (1) the variable is not defined yet, or (2) it doesn't contain a number. The way you avoid that is to always make sure you initialize your variables before you test them. (you did here, you just had the comma problem).

Lastly, while not required on numeric values, it is a good idea to double-quote your variables. This will save you many many headaches along the way.

Upvotes: 3

Related Questions