[bash] How do I write a for loop in bash

I'm looking for the basic loop like:

for(int i = 0; i < MAX; i++) {
  doSomething(i);
}

but for bash.

This question is related to bash for-loop iterator

The answer is


#! /bin/bash

function do_something {
   echo value=${1}
}

MAX=4
for (( i=0; i<MAX; i++ )) ; {
   do_something ${i}
}

Here's an example that can also work in older shells, while still being efficient for large counts:

Z=$(date) awk 'BEGIN { for ( i=0; i<4; i++ ) { print i,"hello",ENVIRON["Z"]; } }'

But good luck doing useful things inside of awk: How do I use shell variables in an awk script?


Try the bash built-in help:


$ help for

for: for NAME [in WORDS ... ;] do COMMANDS; done
    The `for' loop executes a sequence of commands for each member in a
    list of items.  If `in WORDS ...;' is not present, then `in "$@"' is
    assumed.  For each element in WORDS, NAME is set to that element, and
    the COMMANDS are executed.
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
    Equivalent to
        (( EXP1 ))
        while (( EXP2 )); do
            COMMANDS
            (( EXP3 ))
        done
    EXP1, EXP2, and EXP3 are arithmetic expressions.  If any expression is
    omitted, it behaves as if it evaluates to 1.



for ((i = 0 ; i < max ; i++ )); do echo "$i"; done

I commonly like to use a slight variant on the standard for loop. I often use this to run a command on a series of remote hosts. I take advantage of bash's brace expansion to create for loops that allow me to create non-numerical for-loops.

Example:

I want to run the uptime command on frontend hosts 1-5 and backend hosts 1-3:

% for host in {frontend{1..5},backend{1..3}}.mycompany.com
    do ssh $host "echo -n $host; uptime"
  done

I typically run this as a single-line command with semicolons on the ends of the lines instead of the more readable version above. The key usage consideration are that braces allow you to specify multiple values to be inserted into a string (e.g. pre{foo,bar}post results in prefoopost, prebarpost) and allow counting/sequences by using the double periods (you can use a..z etc.). However, the double period syntax is a new feature of bash 3.0; earlier versions will not support this.


The bash for consists on a variable (the iterator) and a list of words where the iterator will, well, iterate.

So, if you have a limited list of words, just put them in the following syntax:

for w in word1 word2 word3
do
  doSomething($w)
done

Probably you want to iterate along some numbers, so you can use the seq command to generate a list of numbers for you: (from 1 to 100 for example)

seq 1 100

and use it in the FOR loop:

for n in $(seq 1 100)
do
  doSomething($n)
done

Note the $(...) syntax. It's a bash behaviour, it allows you to pass the output from one command (in our case from seq) to another (the for)

This is really useful when you have to iterate over all directories in some path, for example:

for d in $(find $somepath -type d)
do
  doSomething($d)
done

The possibilities are infinite to generate the lists.


Bash 3.0+ can use this syntax:

for i in {1..10} ; do ... ; done

..which avoids spawning an external program to expand the sequence (such as seq 1 10).

Of course, this has the same problem as the for(()) solution, being tied to bash and even a particular version (if this matters to you).


I use variations of this all the time to process files...

for files in *.log; do echo "Do stuff with: $files"; echo "Do more stuff with: $files"; done;

If processing lists of files is what you're interested in, look into the -execdir option for files.


if you're intereased only in bash the "for(( ... ))" solution presented above is the best, but if you want something POSIX SH compliant that will work on all unices you'll have to use "expr" and "while", and that's because "(())" or "seq" or "i=i+1" are not that portable among various shells


Examples related to bash

Comparing a variable with a string python not working when redirecting from bash script Zipping a file in bash fails How do I prevent Conda from activating the base environment by default? Get first line of a shell command's output Fixing a systemd service 203/EXEC failure (no such file or directory) /bin/sh: apt-get: not found VSCode Change Default Terminal Run bash command on jenkins pipeline How to check if the docker engine and a docker container are running? How to switch Python versions in Terminal?

Examples related to for-loop

List append() in for loop Prime numbers between 1 to 100 in C Programming Language Get current index from foreach loop how to loop through each row of dataFrame in pyspark TypeScript for ... of with index / key? Is there a way in Pandas to use previous row value in dataframe.apply when previous value is also calculated in the apply? Python for and if on one line R for loop skip to next iteration ifelse How to append rows in a pandas dataframe in a for loop? What is the difference between ( for... in ) and ( for... of ) statements?

Examples related to iterator

Iterating over Typescript Map Update row values where certain condition is met in pandas How to iterate (keys, values) in JavaScript? How to convert an iterator to a stream? How to iterate through a list of objects in C++ How to avoid "ConcurrentModificationException" while removing elements from `ArrayList` while iterating it? How to read one single line of csv data in Python? 'numpy.float64' object is not iterable Python list iterator behavior and next(iterator) python JSON only get keys in first level