Conditionals & Loops

if/case/for/while/until, the [ vs [[ vs (( )) test distinctions, and break/continue.

Overview

Overview Bash provides multiple conditional constructs, and choosing the right one is critical for correctness and portability.

[ ] (test command): The POSIX-compatible test command. It is actually an external command (though bash has a builtin). It does not support regex, and unquoted variables with spaces cause word splitting bugs. Always quote variables: [ "$var" = "value" ].

[[ ]] (bash keyword): Extended test construct — bash-specific. Supports: pattern matching with =~ (regex), = for string comparison with glob patterns, no word splitting so quoting is less critical (though still good practice), && and || inside the brackets. Preferred for bash scripts.

(( )) (arithmetic evaluation): For numeric comparisons and math. (( i++ )), (( count > 5 )), (( result = a * b )). Returns exit code 0 if result is nonzero (truthy), 1 if zero.

File tests: -f (regular file), -d (directory), -r/-w/-x (permissions), -s (nonzero size), -e (exists), -L (symlink), -z (string is empty), -n (string is nonzero length), -nt/-ot (newer/older than).

for loop forms: for item in list (word-split list), for item in "$@" (all script args), for ((i=0; i<10; i++)) (C-style), for file in *.log (glob expansion).

while read pattern: The canonical way to process files line by line. while IFS= read -r line; do ... done < file.txt. IFS= prevents trimming leading/trailing whitespace. -r prevents backslash interpretation.

case statement: Cleaner than chained elif for string pattern matching. Supports wildcards: *, ?, [abc]. Multiple patterns per case with |.

Key concepts

[ ] vs [[ ]] vs (( ))
[ ]: POSIX test — no regex, word splitting on unquoted vars. [[ ]]: bash keyword — supports =~, glob, safer quoting. (( )): arithmetic — numeric comparisons and math, C-like syntax.
Numeric vs string comparison operators
Numeric: -eq -ne -lt -le -gt -ge (only in [ ] or [[ ]]). String: = != (in [[ ]]). Arithmetic: == != = (in (( ))). Mixing them causes bugs.
while read for file processing
while IFS= read -r line; do ... done < file — IFS= preserves leading spaces, -r prevents backslash escape, < file redirects without subshell (variables persist after loop).
case pattern matching
case $var in pattern) commands ;; esac. Patterns support *, ?, [abc]. Multiple patterns: pattern1|pattern2). Cleaner than long elif chains for fixed string matching.

When to use it

  • Writing conditional logic in shell scripts
  • Processing files line by line
  • Input validation in scripts
  • Building menus or option parsers

Interview questions

  • What is the difference between [ ], [[ ]], and (( )) in bash conditionals?
  • Write a bash script that reads a file line by line and processes each line safely, including lines with spaces.

Sign up free to read the full topic

More Linux topics

Start free on Cariara · Coding problems · System design studio