Bash test operators
Bash conditional expressions decide which branch of an if, while or &&
chain runs. They live inside the test command, its [ ] alias, or the more
capable [[ ]] keyword. The operators fall into clear families: file-attribute
tests, string emptiness checks, string and numeric comparisons, regex matching,
and logical combinators. This page is a searchable, offline reference with a
working example for every operator.
How it works
A test operator evaluates to a true (exit status 0) or false (non-zero) result, which the surrounding control structure uses:
- File tests are unary operators like
-f(regular file),-d(directory) and-x(executable) that inspect a path, plus binary comparisons-nt,-otand-efthat compare two files by timestamp or inode. - String tests
-zand-ncheck for an empty or non-empty value. - Comparison uses
=/==/!=for strings and-eq,-ne,-lt,-le,-gt,-gefor integers — never mix the two. - Regex uses
[[ s =~ re ]], available only in double brackets, storing captures inBASH_REMATCH. - Logical operators negate (
!) or combine (&&,||, or the legacy-a,-o).
The most important rule: prefer [[ ]] for new scripts. It avoids word-splitting
surprises, supports glob and regex matching, and lets you use &&/|| inside a
single test.
Tips and examples
Always quote variables in [ ] to avoid syntax errors when a value is empty or
contains spaces:
if [ -z "$name" ]; then
echo "name is empty"
fi
Combine conditions cleanly inside double brackets:
if [[ -f "$config" && -r "$config" ]]; then
source "$config"
fi
Capture parts of a match with a regex:
if [[ "$ver" =~ ^([0-9]+)\.([0-9]+)$ ]]; then
major=${BASH_REMATCH[1]}
minor=${BASH_REMATCH[2]}
fi
Remember the numeric-versus-string distinction: use -eq family operators for
integers and =/!= for text, or comparisons will silently give the wrong
answer.