I am supplying a while loop with the following

while [ -z "$number2" ] | [ "$number2" == 404 ] & [ "$number2" != 200 ] & [ "$number1" -lt 13 ]; do
  #number2=$(some command which can actually get a number)
  number2=200 # <<< e.g. a command that would return 
  let number1=number1+1

This is what I need to do

If number2 is null do the loop
If number2 is 404 do the loop
If number2 is 200 don't do the loop
Do the loop until number1 is 12

When I try the loop with number2=200 it doesn't stop. It seems I am having a challenge with having it to stop where number2 is 200.

How do I write the statement such that it will stop the while loop when number2=200 or is there an alternative?

  • What would happen if $number2 is 300 or 500?
    – Kusalananda
    Commented Dec 14, 2018 at 10:14
  • @Kusalananda $number2 is either null 404 or 200 Commented Dec 14, 2018 at 10:39

2 Answers 2


If number2 is null do the loop
If number2 is 404 do the loop
If number2 is 200 don't do the loop
Do the loop until number1 is 12

In other words, repeat as long as (number2 is null OR number2 = 404) AND (number2 != 200) AND (number1 <= 12). Note that you need some sort of grouping here, to make the precedence of AND and OR explicit. (In Bash, && and || operate from left to right, but often the AND-operator binds more strongly than an OR-operator.)

Though you didn't say what should happen for other values of number2, so we might as well drop the first two conditions, since if number2 is null or 404, then it can't be 200. So we get (number2 != 200) AND (number1 <= 12).


while [ -z "$number2" ] | [ "$number2" == 404 ] & [ "$number2" != 200 ] & [ "$number1" -lt 13 ]; do ...

you have | and & instead of || and &&. | indicates a pipeline, and & runs the preceding command in the background. So the above would run three commands in parallel: one pipeline with two tests, and another with one test, both in the background; and one test in the foreground. That doesn't make much sense. I mentioned && and || above, those are the logical condition operators in Bash.

The simplified form would be:

while [ "$number2" != 200 ] && [ "$number1" -le 12 ]; do ...

(You may also want to use somewhat more descriptive variable names than "number1" and "number2".)

  • Thanks.. let me go through the commands and see if i need more clarity Commented Dec 14, 2018 at 10:43

Logical operators in the shell are && and ||. The & and | does very different things (starts a background task and sets up a pipe between two processes, respectively).



while [ "$number1" -le 12 ]; do

    number2=$( some command )

    case $number2 in
            # nothing
            printf 'Unexpected: number2 = %s\n' "$number2" >&2
            exit 1

    number1=$(( number1 + 1 ))


The number in $number2 looks like a HTTP status code. Testing the value in a case statement as above would allow you to select the correct action given any number of status codes without making the shell code an unwieldy mess of if-statements. For example, the action for any client or server failure code could be triggered by the pattern 4??|5??.

This also logically separates the semantics of the two variables. The number1 variable controls the number of iterations, while number2 is strictly for controlling the action to take based on the outcome of your mystery command.

  • ya the mystery command returns HTTP code and I want to do recheck if with another number if I get 404 again and stop if I get 200 and do something after Commented Dec 14, 2018 at 11:05
  • @BretJoseph In that case, you may want to do an additional check after the loop to make sure that you know why the loop terminated. It can terminate because of having run 12 times, or it may terminate because you got your 200 status.
    – Kusalananda
    Commented Dec 14, 2018 at 11:07
  • as long as it stops after the 200 status or re-loops if not its fine, I will make it do something before it breaks Commented Dec 14, 2018 at 11:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .