bashshell

Bash loop until a certain command stops failing


I would like to write a loop in bash which executes until a certain command stops failing (returning non-zero exit code), like so:

while ! my_command; do
    # do something
done

But inside this loop I need to check which exit code my_command returned, so I tried this:

while ! my_command; do
    if [ $? -eq 5 ]; then
        echo "Error was 5"
    else
        echo "Error was not 5"
    fi
    # potentially, other code follows...
done

But then the special variable ? becomes 0 inside the loop body. The obvious solution is:

while true; do
    my_command
    EC=$?
    if [ $EC -eq 0 ]; then
        break
    fi
    some_code_dependent_on_exit_code $EC
done

How can I check the exit code of my_command (called in loop header) inside loop body without rewriting this example using a while true loop with a break condition as shown above?


Solution

  • In addition to the well-known while loop, POSIX provides an until loop that eliminates the need to negate the exit status of my_command.

    # To demonstrate
    my_command () { read number; return $number; }
    
    until my_command; do
        if [ $? -eq 5 ]; then
            echo "Error was 5"
        else
            echo "Error was not 5"
        fi
        # potentially, other code follows...
    done