= 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