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?
Infinite while Loop You can also use the true built-in or any other statement that always returns true. The while loop above will run indefinitely. You can terminate the loop by pressing CTRL+C .
The bash wait command is a Shell command that waits for background running processes to complete and returns the exit status. Unlike the sleep command, which waits for a specified time, the wait command waits for all or specific background tasks to finish.
Using break Inside for Loops To add a conditional statement and exit a for loop early, use a break statement. The following code shows an example of using a break within a for loop: #!/bin/bash for i in {1.. 10} do if [[ $i == '2' ]] then echo "Number $i!" break fi echo "$i" done echo "Done!"
Exit When Any Command Fails This can actually be done with a single line using the set builtin command with the -e option. Putting this at the top of a bash script will cause the script to exit if any commands return a non-zero exit code.
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
If true
command hurt your sensibility, you could write:
while my_command ; ret=$? ; [ $ret -ne 0 ];do
echo do something with $ret
done
This could be simplified:
while my_command ; ((ret=$?)) ;do
echo do something with $ret
done
But if you don't need ResultCode, you could simply:
while my_command ; [ $? -ne 0 ];do
echo Loop on my_command
done
or
while my_command ; (($?)) ;do
echo Loop on my_command
done
And maybe, why not?
while ! my_command ;do
echo Loop on my_command
done
But from there you could better use until
as chepner suggest
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With