testing

[[ ]]

Bash-specific conditional expression with safer parsing, glob and regex matching, and short-circuit logical operators. No word splitting or filename expansion happens on the arguments, so quoting is far less error-prone than [ ] — but [[ ]] is not POSIX.

[[ EXPR ]]

Common flags / operators

Flag / Operator Purpose
== != String compare; RHS is a glob unless quoted
=~ Regex match — captures land in ${BASH_REMATCH[@]}
&& || Logical AND / OR (inside [[ ]])
< > Lexicographic string compare (no escaping needed)
-v NAME True if variable NAME is set (even to empty)
file tests -f / -d / -e / -r / -w / -x work as in [ ]

Examples

[[ $file == *.log ]] && echo log

Glob match — no need to quote RHS.

[[ $email =~ ^[a-z]+@[a-z]+\.[a-z]+$ ]]

Regex match; matched groups in ${BASH_REMATCH[1]}...

[[ -n $var && $var != skip ]]

Chained conditions using && inside [[ ]].

[[ -v CONFIG ]]

True if CONFIG is set — distinguishes unset from empty.

Gotcha

Quoting the RHS of == turns off glob matching: [[ $x == 'a*' ]] tests literal 'a*'. [[ ]] is NOT POSIX — scripts starting with '#!/bin/sh' should stick to [ ].

Related

← All Bash builtins · Linux commands