= Bash Looping =

<<TableOfContents>>

----



== For Loops ==

The `for` loop iterates over a list. The list can be anything from a literal list of items (`1 2 3`) to a process expansion (`$(seq 1 3)`) to a filename expansion (`*`). See [[Bash/Expansion|here]] for more details.

{{{
for filename in *; do
  chmod 755 "$filename"
done
}}}

If a list is not specified, `bash(1)` implicitly loops over `"$@"`.

{{{
for arg; do
  if [[ "$arg" = "-h" ]]; then
    echo "$help_message"
  fi
done
}}}

To immediately skip to the next iteration, use the `continue` [[Bash/BuiltinCommands#Continue|builtin]].

{{{
for arg; do
  if [[ "$arg" != "-h" ]]; then
    continue
  fi
  echo "$help_message"
done
}}}

To immediately exit the loop, use the `break` [[Bash/BuiltinCommands#Break|builtin]].

{{{
for arg; do
  if [[ "$arg" = "-h" ]]; then
    echo "$help_message"
    break
  fi
done
}}}



=== C-Style ===

For more complex looping structures, consider using a C-style `for` loop.

As an example, to check if a word is a palindrome, try:

{{{
word="$1"
len=${#word}
for (( i=0,j=len-1; i<(len/2); i++,j-- )); do
  [[ "${word:i:1}" != "${word:j:1}" ]] && exit 1    
done                                            
exit 0
}}}

This example makes use of substring expansion; see [[Bash/Expansion#Substring_Parameter_Expansion|here]] for details.

The key to this grammar is the semicolons (`;`). There must be three semicolon delimited expressions, all of which are parsed as [[Bash/Arithmetic|arithmetic]]. The first is evaluated once. The second is evaluated repeatedly until it evaluates to 0. For each evaluation of the second, all of the commands of the `for` loop are executed ''and'' the third expression is evaluated.

----



== While Loops ==

The `while` loop iterates as long as the condition evaluates to true.

As an example, to replace spaces with underscores (`_`), try:

{{{
word="$1"
i=0
while [[ "$i" < "${#word}" ]]; do
  [[ "${word:i:1}" = " " ]] && word="${word::i}_${word:i+1}"
  (( i++ ))
done
echo $word
}}}

This example makes use of [[Bash/Expansion#Substring_Parameter_Expansion|substring expansion]] and [[Bash/Arithmetic|arithmetic]]; see those articles for more details.

To immediately skip to the next iteration, use the `continue` [[Bash/BuiltinCommands#Continue|builtin]]. To immediately exit the loop, use the `break` [[Bash/BuiltinCommands#Break|builtin]].

----



== Until Loops ==

`until` loops are the inverse of a `while` loops.

As an example, to repeatedly prompt a user until a valid response is detected, try:

{{{
echo "Create file 'config.toml'? [y/N]: "
until [[ -e "config.toml" ]]; do
  read RESPONSE
  case "$RESPONSE" in
    [Yy]) touch "config.toml";;
    [Nn]) exit 1;;
    *) echo "Please enter Y or N";;
  esac
done
}}}

To immediately skip to the next iteration, use the `continue` [[Bash/BuiltinCommands#Continue|builtin]]. To immediately exit the loop, use the `break` [[Bash/BuiltinCommands#Break|builtin]].



----
CategoryRicottone