11

Below is my shell script. How to compare the exit status of function in while loop condition block ? Whatever I return from check1 function my code enters into while loop

#!/bin/sh
    check1()
    {
            return 1
    }

    while [ check1 ]
    do
            echo $?
            check1
            if [ $? -eq 0 ]; then
                    echo "Called"
            else
                    echo "DD"
            fi
            sleep 5
    done
1
  • I'm not sure why you're calling check1 twice? You should be able to assumed it was "Called" each time through that loop... Commented Jun 23, 2021 at 16:28

3 Answers 3

18

Remove the test command - also known as [. So:

while check1
do
    # Loop while check1 is successful (returns 0)

    if check1
    then
        echo 'check1 was successful'
    fi

done

Shells derived from the Bourne and POSIX shells execute a command after a conditional statement. One way to look at it is that while and if test for success or failure, rather than true or false (although true is considered successful).

By the way, if you must test $? explicitly (which is not often required) then (in Bash) the (( )) construct is usually easier to read, as in:

if (( $? == 0 ))
then
    echo 'worked'
fi
Sign up to request clarification or add additional context in comments.

Comments

10

The value returned by a function (or command) execution is stored in $?, one solution would be:

check1
while [ $? -eq 1 ]
do
    # ...
    check1
done

A nicer and simpler solution may be:

while ! check1
do
    # ...
done

In this form zero is true and non-zero is false, for example:

# the command true always exits with value 0
# the next loop is infinite
while true
    do
    # ...

You can use ! to negate the value:

# the body of the next if is never executed
if ! true
then
    # ...

1 Comment

You might also consider until rather than while !
0

For completeness, another way is using the function exit code inline of the while

 while check1  ; [ $? -eq 0 ] ; do

from here

You can also use parameters if you change your method to the "echo" style return value.

 while [ $(check1 my_param) < 33] ; do ...

2 Comments

This would fail if your script uses set -e, which is the most important line that every single Bash script should always include at the top: Automatically terminate if a command fails without being caught intentionally. Running without set -e is disastrously dangerous. And your second example is even worse, because $() literally creates a second Bash process (a sub-shell) and is super wasteful. Anyway, you should ALWAYS be using while the_function; and optionally while ! the_function; (although that one's unusual) to handle function error checking in the correct, Bash way.
Oh and your first example is just doing what while the_function; does, but doing it incorrectly and failing if set -e is active (as it should always be). The fact is, while takes a statement and evaluates it, and continues again if the return code was 0, or aborts if the return code was any other value. That's how it works and why you should only use that method. Hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.