⚖️ Extended Conditionals and Tests
Conditional logic forms the backbone of every non-trivial script. This section covers both basic and advanced testing mechanisms.
🧭 Test Command Fundamentals
The test command (or its alias [) evaluates conditions and returns exit code:
1 2 3 | |
Key points:
- Spaces around [ and ] are mandatory
- Use = for string comparison (not == in POSIX)
- Quote variables to prevent word splitting
🧪 File Tests
| Operator | Meaning | Example |
|---|---|---|
-e FILE |
Exists | [ -e /etc/passwd ] |
-f FILE |
Regular file | [ -f script.sh ] |
-d DIR |
Directory | [ -d /home ] |
-r FILE |
Readable | [ -r config.yml ] |
-w FILE |
Writable | [ -w /tmp ] |
-x FILE |
Executable | [ -x /usr/bin/grep ] |
-s FILE |
Size > 0 | [ -s data.txt ] |
-L FILE |
Symbolic link | [ -L /usr/bin/python ] |
-nt F1 F2 |
F1 newer than F2 | [ file1 -nt file2 ] |
-ot F1 F2 |
F1 older than F2 | [ file1 -ot file2 ] |
🧠 String Comparisons
| Operator | Meaning | POSIX? |
|---|---|---|
= |
Equal | ✅ |
!= |
Not equal | ✅ |
-z STR |
Empty string | ✅ |
-n STR |
Non-empty string | ✅ |
Examples:
1 2 3 4 5 6 7 8 | |
⚠️ Avoid == in POSIX scripts — use = instead.
🧪 Numeric Comparisons
| Operator | Meaning | Example |
|---|---|---|
-eq |
Equal | [ $count -eq 0 ] |
-ne |
Not equal | [ $count -ne 0 ] |
-lt |
Less than | [ $age -lt 18 ] |
-le |
Less or equal | [ $retries -le 3 ] |
-gt |
Greater than | [ $size -gt 100 ] |
-ge |
Greater or equal | [ $score -ge 90 ] |
Important: These operators work only with integers.
1 2 3 4 | |
🧠 Logical Operators
Combine multiple conditions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Group with parentheses (escaped in POSIX):
1 2 3 | |
🧪 Bash/Zsh Extended Tests
Double brackets [[ ]] offer more features:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Advantages of [[ ]]:
- No word splitting on unquoted variables
- Supports && and || inside
- Supports regex with =~
- Supports pattern matching with ==
⚠️ Not POSIX — avoid in portable scripts.
🧠 Case Statements
For multiple string comparisons, case is cleaner than nested if:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Pattern matching in case:
1 2 3 4 5 6 7 8 9 10 11 | |
🧪 Arithmetic Conditions
Bash supports arithmetic evaluation:
1 2 3 4 5 6 7 | |
Or with let:
1 2 3 4 | |
🧾 Portability Comparison
| Feature | POSIX [ ] |
Bash [[ ]] |
|---|---|---|
| String equality | = |
= or == |
| Pattern matching | ❌ | ✅ |
| Regex matching | ❌ | ✅ |
| Logical AND/OR | -a / -o |
&& / || |
| Word splitting | ⚠️ Quote! | ✅ Safe |
| Arithmetic | ❌ | ✅ (( )) |
🧾 Summary
- Use
[ ]for portable scripts — always quote variables. - Use
[[ ]]for Bash/Zsh-specific features. - Prefer
caseover nestediffor multiple branches. - Numeric tests use
-eq,-lt, etc. — not==,<, etc. - Combine conditions with
&&,||,!for complex logic.
👉 Continue to: Loops and Iteration