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