3

I am supplying a while loop with the following

#!/bin/bash
number1=1
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
done

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 Dec 14 '18 at 10:14
  • @Kusalananda $number2 is either null 404 or 200 – Bret Joseph Dec 14 '18 at 10:39
7

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

Here,

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 – Bret Joseph Dec 14 '18 at 10:43
5

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


#!/bin/sh

number1=1

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

    number2=$( some command )

    case $number2 in
        200)
            break
            ;;
        ""|404)
            # nothing
            ;;
        *)
            printf 'Unexpected: number2 = %s\n' "$number2" >&2
            exit 1
    esac

    number1=$(( number1 + 1 ))

done

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 – Bret Joseph Dec 14 '18 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 Dec 14 '18 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 – Bret Joseph Dec 14 '18 at 11:10

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.