Lesson 7 / 25
Tests: [[ ]], [ ] and (( ))
Write string, numeric and file tests correctly.
How Bash decides true or false
In Bash, if runs a command and branches on its exit status: 0 is true, non-zero is false. Test commands make conditions. [ ... ] (the test command) is POSIX and works in any shell, but needs careful quoting. [[ ... ]] is a Bash keyword that is safer and more capable: no word splitting of variables inside it, && and || inside the brackets, pattern matching with == ([[ $file == *.log ]]) and regular expressions with =~ (captures in BASH_REMATCH). String tests: -z (empty), -n (non-empty), ==, !=. Numeric tests inside brackets use -eq, -ne, -lt, -le, -gt, -ge; < and > inside [[ ]] compare strings alphabetically, which is a common bug. For numbers, prefer (( ... )), an arithmetic test where (( count > 10 )) works naturally. File tests: -e exists, -f regular file, -d directory, -r/-w/-x permissions, -s non-empty, -L symlink.
Exit status drives every decision
if, while and && all branch on whether a command returned 0.
Common tests
Strings, numbers, files and patterns.
name="report.log"
count=12
if [[ -z "$name" ]]; then echo "empty name"; fi
if [[ $name == *.log ]]; then echo "a log file"; fi
if [[ $name =~ ^([a-z]+)\.log$ ]]; then echo "base: ${BASH_REMATCH[1]}"; fi
if (( count > 10 )); then echo "more than ten"; fi
if [[ $count -ge 10 && -f /etc/hosts ]]; then echo "both true"; fi
[[ "10" < "9" ]] && echo "string compare: '10' sorts before '9'" # trap!
if [[ -d /var/log && -r /var/log/syslog ]]; then echo "can read syslog"; fiUse (( )) for numbers
[[ 10 > 9 ]] compares strings, and "10" sorts before "9", so the test is false. Write numeric comparisons as (( a > b )) or with -gt to avoid this trap.
Quick check: Which test correctly checks whether the number in $n is greater than 10?
- (( n > 10 ))
- [[ $n > 10 ]]
- [ $n > 10 ]
- [[ $n == >10 ]]
Answer
(( n > 10 )) — Arithmetic evaluation compares numbers; > inside [[ ]] compares strings and inside [ ] is a redirection.