Free tools Windows power users keep installed
One-click scans. No signup required.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
An infinite while loop in Bash runs while its condition returns exit status 0. The clearest form is:
while true; do
command
sleep 1
done
The traditional equivalent is while :. Both work because true and the Bash null command : always return success. Use an explicit exit path such as break, a signal trap, or a controlled condition when the loop should eventually stop.
How a Bash while loop becomes infinite
The general syntax is:
while condition
do
commands
done
Bash runs the commands while the condition command or compound command returns status 0. A nonzero status ends the loop. Therefore, a condition that always succeeds creates an intentional infinite loop:
while true; do
# Work performed repeatedly
done
When do is on the same line as the condition, separate it with a semicolon:
#1 Best Overall
while true; do
printf '%sn' "Running"
done
With multiline formatting, the semicolon is unnecessary.
What : means
: is Bash’s null command, also called the no-op command. It performs no operation and returns success:
:
printf 'status: %sn' "$?" # status: 0
Thus, this loop means “run while the null command succeeds”:
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemswhile :; do
printf '%sn' "Still running"
sleep 1
done
It is not a special forever keyword. It is simply a command whose successful status keeps the while condition true. The form is a traditional shell idiom, while while true is often easier for beginners and maintenance programmers to understand.
while : versus while true
| Form | Best use | Notes |
|---|---|---|
while true |
Clear, self-documenting scripts | Usually the easiest form to recognize |
while : |
Traditional shell code | Uses the shell’s null command |
while (( 1 )) |
Bash arithmetic syntax | Valid, but less idiomatic here |
while [ 1 ] |
Technically valid shell code | Obscure; avoid it for readability |
There is no meaningful practical performance reason to choose one over the other for normal scripts. Choose the form that communicates intent to the people who will read the code.
Why while false does not loop
false returns a nonzero status, so the body is skipped immediately:
while false; do
printf '%sn' "This never runs"
done
The three basic statuses are easy to demonstrate:
true
printf 'true status: %sn' "$?" # 0
:
printf 'colon status: %sn' "$?" # 0
false
printf 'false status: %sn' "$?" # 1
Runnable example
Create a script with a deliberate one-second delay:
cat > infinite-loop.sh <<'EOF'
#!/usr/bin/env bash
while true; do
printf '%sn' 'Still running; press Ctrl+C to stop.'
sleep 1
done
EOF
chmod +x infinite-loop.sh
./infinite-loop.sh
Press Ctrl+C to normally send SIGINT to the foreground process group. This is convenient for testing, but a long-running script should usually also provide an intentional shutdown path.
Ways to stop an infinite loop
Use break
break exits the innermost enclosing loop and lets the rest of the script continue:
#!/usr/bin/env bash
while true; do
read -r -p 'Enter q to quit: ' answer
if [[ $answer == q ]]; then
break
fi
printf 'You entered: %sn' "$answer"
done
printf '%sn' 'Loop ended'
In nested loops, break 2 exits two loop levels.
Use exit
Use exit when the entire script must terminate, not merely the loop:
while true; do
if some_fatal_condition; then
printf '%sn' 'Fatal error' >&2
exit 1
fi
do_work
done
Use a shutdown flag
A flag makes the loop’s termination state explicit:
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchrunning=1
while (( running )); do
if should_stop; then
running=0
else
do_work
fi
done
cleanup
Handle termination signals
For a worker or polling script, trap INT and TERM and perform cleanup after the loop:
#!/usr/bin/env bash
stop_requested=0
on_signal() {
stop_requested=1
}
trap on_signal INT TERM
while (( ! stop_requested )); do
do_work
sleep 1
done
cleanup
printf '%sn' 'Shutting down cleanly'
A simple trap is suitable for introductory scripts. If the loop starts background jobs or external processes, shutdown may also need to wait for or terminate those child processes. Ctrl+C is not a universal cleanup strategy: signals can be trapped, ignored, delivered to wrappers, or behave differently for background jobs.
Read input safely in an infinite loop
For interactive commands, check the status of read so end-of-file does not leave the script waiting or processing an invalid value:
while true; do
if ! IFS= read -r -p 'Command: ' command; then
printf '%sn' 'End of input'
break
fi
case $command in
quit|exit)
break
;;
*)
printf 'Unknown command: %sn' "$command"
;;
esac
done
IFS= preserves leading and trailing whitespace, and -r prevents read from treating backslashes as escape characters. In Bash, [[ ... ]] is generally preferable for string tests because it avoids several word-splitting and quoting pitfalls.
Menu-driven example
#!/usr/bin/env bash
while true; do
printf 'n'
printf '%sn'
'1) Show date'
'2) Show current directory'
'3) Quit'
if ! read -r -p 'Choose an option: ' choice; then
printf '%sn' 'End of input'
break
fi
case $choice in
1)
date
;;
2)
pwd
;;
3)
printf '%sn' 'Goodbye.'
break
;;
*)
printf '%sn' 'Invalid choice.' >&2
;;
esac
done
Prevent a busy loop
This loop may consume substantial CPU if check_status returns immediately:
while true; do
check_status
done
Add a delay when polling:
while true; do
check_status
sleep 5
done
Subsecond polling is possible, but it should be deliberate:
while true; do
check_status
sleep 0.2
done
A delay is not required when the loop blocks naturally on input, a socket, or another event source. The important rule is that a loop must either do useful blocking work or rate-limit repeated checks. Also avoid printing on every fast iteration, since redirected output can rapidly fill a terminal, log, or disk.
Rank #4
Prefer a condition when termination is known
An explicit condition makes a termination guarantee visible. For bounded retries:
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →attempt=1
max_attempts=5
while (( attempt <= max_attempts )); do
if command_succeeds; then
break
fi
(( attempt++ ))
sleep 2
done
Use until when the natural meaning is “keep trying until this command succeeds”:
until check_ready; do
printf '%sn' 'Not ready; retrying...'
sleep 1
done
Do not use an unbounded loop for a retry policy that should have a timeout, maximum attempt count, or failure condition.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Common mistakes
Forgetting to update loop state
n=1
while (( n < 10 )); do
echo "$n"
# Missing: (( n++ ))
done
The condition never changes, so this is an accidental infinite loop. Add the state update:
(( n++ ))
Confusing a blocking read with a hang
In this loop, the script waits for input at read:
while true; do
read -r value
[[ $value == quit ]] && break
done
That behavior is expected. Handle EOF explicitly if the script may receive redirected or piped input.
Starting unbounded background work
while true; do
do_work &
sleep 1
done
The ampersand starts asynchronous work. If each job takes longer than a second, processes can accumulate without limit. Use wait, a concurrency limit, or a worker design that applies backpressure.
Best Value
Assuming set -e solves loop termination
set -e is not a timeout or universal loop-safety mechanism. Bash’s errexit behavior depends on context, and it does not replace an explicit exit condition, signal policy, or resource limit.
Pipeline subshell behavior
Variables assigned inside a piped loop may not be available afterward because the loop can execute in a subshell:
printf '%sn' a b c | while read -r item; do
last=$item
done
printf '%sn' "$last"
When you need the loop’s variable afterward, process substitution is often appropriate in Bash:
while IFS= read -r item; do
last=$item
done < <(printf '%sn' a b c)
printf '%sn' "$last"
Bash and POSIX portability
while : is portable shell syntax, and while true is widely supported by Unix shells. The following features in this article are Bash-specific or Bash-oriented: [[ ... ]], (( ... )), process substitution, and the #!/usr/bin/env bash interpreter line.
For Bash grammar and builtins, see the Bash Reference Manual. For portable shell rules, consult the POSIX Shell Command Language specification.
When an infinite loop is the right tool
Infinite loops are not inherently bad. They are appropriate for interactive menus, workers, polling processes, and long-running consumers when the script has a controlled shutdown method, sensible resource use, and clear error handling.
For a real production service, consider whether a service manager such as systemd should own restarting, logging, dependencies, timeouts, and signal behavior instead of placing all those responsibilities in a shell loop.
Recommended Free Tools
Quick Recap
Quick reference
# Explicit infinite loop
while true; do
work
done
# Traditional shell idiom
while :; do
work
done
# Stop the current loop
break
# Stop the entire script
exit 1
# Bounded loop
while (( attempts < max_attempts )); do
work
(( attempts++ ))
done
# Wait until a command succeeds
until check_ready; do
sleep 1
done
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

