Bash counter: loop counters, increment patterns, and script counters (`for`, `while`)

Tech reviewed: Deepak Prasad
Bash counter: loop counters, increment patterns, and script counters (`for`, `while`)

A bash counter is usually an integer you bump each time around a loop: a bash loop counter in a for ((…)) header, a bash while loop counter you increment in the body, or a bash script counter that tracks how many files, lines, or matches you processed. This page ties those patterns together; for every detail on ++ vs pre-increment and $(( )) vs (( )), read bash increment variable.

I re-ran the snippets below on Ubuntu 25.04, kernel 6.14.0-37-generic, Bash 5.2.37.


Bash for loop counter (for (( )))

The clearest bash for loop counter is the C-style for (( i=0; i<n; i++ )) form: the counter lives in the loop header.

bash
for ((i = 0; i < 3; i++)); do
  echo "i=$i"
done
text
i=0
i=1
i=2

You can also advance with ((i+=1)) or let i+=1 in the third slot or inside the body if you need irregular steps.


Bash while loop counter

A bash while loop counter starts before the loop and moves inside the body:

bash
n=0
while ((n < 3)); do
  echo "n=$n"
  ((n++))
done
text
n=0
n=1
n=2

Use ((n+=1)) for steps other than one. Avoid n=$((n++)) in assignments: $((var++)) returns the old value, so it is a poor way to “increment n and pass the new value around” unless you really mean post-increment semantics.


Bash until loop counter

Same idea as while, but the guard is inverted:

bash
n=0
until ((n > 2)); do
  echo "n=$n"
  ((n += 1))
done
text
n=0
n=1
n=2

Bash for count over a list (not only numeric indexes)

bash for count often means “how many items did I touch?” when you loop over strings or paths. You can keep a separate counter:

bash
c=0
for _ in a b c; do
  echo "c=$c"
  ((c++))
done
text
c=0
c=1
c=2

Or use the index from {arr[@]} if you already have an array—see bash for loop for more list patterns.


Bash script counter: example over files

Here the counter labels each file as you walk a glob:

bash
dir=$(mktemp -d)
touch "$dir"/{a,b,c}.txt
i=0
for f in "$dir"/*.txt; do
  echo "file $((++i)): $(basename "$f")"
done
rm -rf "$dir"
text
file 1: a.txt
file 2: b.txt
file 3: c.txt

$((++i)) bumps i before the value is used, which reads naturally as “first file is number 1”. For “0-based index printed after increment”, use i++ on its own line instead of inside echo.


let, (( )), and $(( )) (quick recap)

  • (( n++ )) or (( ++n )) — arithmetic command, no $ needed.
  • n=$((n + 1)) — classic assignment with arithmetic expansion.
  • let "n = n + 1" — older style; quotes help when tokens look like options.

All of these show up in shell script counter loops; pick one style per script so readers are not bounced between idioms.



Summary

A bash counter is an integer you move each iteration: use a bash for loop counter in for ((i=0; i<n; i++)), a bash while loop counter (or until) with ((i++)) in the body, or a bash for count variable when you loop over values instead of indexes. For bash increment counter mechanics, prefer (( )) and avoid confusing $((var++)) assignments unless you understand post-increment. bash script counter patterns apply whenever you need human-readable sequence numbers alongside real work (files, rows, checks).

Omer Cakmak

Linux Administrator

Highly skilled at managing Debian, Ubuntu, CentOS, Oracle Linux, and Red Hat servers. Proficient in bash scripting, Ansible, and AWX central server management, he handles server operations on OpenStack, KVM, Proxmox, and VMware.

  • Debian
  • Ubuntu
  • Linux
  • Red Hat Enterprise Linux