There is no do-while loop in bash. To execute a command first then run the loop, you must either execute the command once before the loop or use an infinite loop with a break condition.
bash (or Posix shells in general) don't have an explicit syntax for a post-test loop (commonly known as a "do-while" loop) because the syntax would be redundant.
Dollar sign $ (Variable) The dollar sign before the thing in parenthesis usually refers to a variable. This means that this command is either passing an argument to that variable from a bash script or is getting the value of that variable for something.
Two simple solutions:
Execute your code once before the while loop
actions() {
check_if_file_present
# Do other stuff
}
actions #1st execution
while [ current_time <= $cutoff ]; do
actions # Loop execution
done
Or:
while : ; do
actions
[[ current_time <= $cutoff ]] || break
done
Place the body of your loop after the while
and before the test. The actual body of the while
loop should be a no-op.
while
check_if_file_present
#do other stuff
(( current_time <= cutoff ))
do
:
done
Instead of the colon, you can use continue
if you find that more readable. You can also insert a command that will only run between iterations (not before first or after last), such as echo "Retrying in five seconds"; sleep 5
. Or print delimiters between values:
i=1; while printf '%d' "$((i++))"; (( i <= 4)); do printf ','; done; printf '\n'
I changed the test to use double parentheses since you appear to be comparing integers. Inside double square brackets, comparison operators such as <=
are lexical and will give the wrong result when comparing 2 and 10, for example. Those operators don't work inside single square brackets.
This implementation:
do=true
while $do || conditions; do
do=false
# your code ...
done
It works with a read loop, too, skipping the first read:
do=true
while $do || read foo; do
do=false
# your code ...
echo $foo
done
We can emulate a do-while loop in Bash with while [[condition]]; do true; done
like this:
while [[ current_time <= $cutoff ]]
check_if_file_present
#do other stuff
do true; done
For an example. Here is my implementation on getting ssh connection in bash script:
#!/bin/bash
while [[ $STATUS != 0 ]]
ssh-add -l &>/dev/null; STATUS="$?"
if [[ $STATUS == 127 ]]; then echo "ssh not instaled" && exit 0;
elif [[ $STATUS == 2 ]]; then echo "running ssh-agent.." && eval `ssh-agent` > /dev/null;
elif [[ $STATUS == 1 ]]; then echo "get session identity.." && expect $HOME/agent &> /dev/null;
else ssh-add -l && git submodule update --init --recursive --remote --merge && return 0; fi
do true; done
It will give the output in sequence as below:
Step #0 - "gcloud": intalling expect..
Step #0 - "gcloud": running ssh-agent..
Step #0 - "gcloud": get session identity..
Step #0 - "gcloud": 4096 SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /builder/home/.ssh/id_rsa (RSA)
Step #0 - "gcloud": Submodule '.google/cloud/compute/home/chetabahana/.docker/compose' ([email protected]:chetabahana/compose) registered for path '.google/cloud/compute/home/chetabahana/.docker/compose'
Step #0 - "gcloud": Cloning into '/workspace/.io/.google/cloud/compute/home/chetabahana/.docker/compose'...
Step #0 - "gcloud": Warning: Permanently added the RSA host key for IP address 'XXX.XX.XXX.XXX' to the list of known hosts.
Step #0 - "gcloud": Submodule path '.google/cloud/compute/home/chetabahana/.docker/compose': checked out '24a28a7a306a671bbc430aa27b83c09cc5f1c62d'
Finished Step #0 - "gcloud"
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