Fundamentals 6 min read

Master Bash test, [, and [[: Uncover Truthy and Falsy Logic in Shell Scripts

This article demystifies Bash's test constructs—including test, [, [[, and (( ))—explaining their syntax, return codes, common operators, and practical examples so readers can confidently write conditional logic in shell scripts.

Tencent IMWeb Frontend Team
Tencent IMWeb Frontend Team
Tencent IMWeb Frontend Team
Master Bash test, [, and [[: Uncover Truthy and Falsy Logic in Shell Scripts

Understanding Bash test

The

test

command in Bash often confuses beginners, but once grasped it reveals no deep mystery.

Real‑world example

<code>export NVM_DIR="/Users/jero/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"  # This loads nvm
</code>

In the snippet above, the brackets

[ ... ]

perform a test that checks whether the

nvm.sh

script exists before sourcing it.

<code>if [ "$(uname)" == 'Darwin' ]; then
  OS='Mac'
elif [ "$(expr substr $(uname -s) 1 5)" == 'Linux' ]; then
  OS='Linux'
else
  echo "Your platform ($(uname -a)) is not supported."
  exit 1
fi
</code>

This

if

statement also relies on

[ ... ]

as a test to determine the operating system.

test and [

Both

test

and

[

evaluate an expression using

expr

and return 0 for true or 1 for false. They are interchangeable:

<code>test 3 -gt 4 && echo True || echo False  # False
[ 3 -gt 4 ] && echo True || echo False  # False
[ 'abc' != 'def' ]; echo $?               # 0
</code>

The special variable

$?

holds the exit status of the previous command. The operator

-gt

means “greater than”.

Numeric comparison operators

-gt

: greater than

-ge

: greater than or equal

-eq

: equal

-ne

: not equal

-lt

: less than

-le

: less than or equal

Examples of return codes

<code>[ 3 -gt 4 ]; echo $?   # 1 (false)
[ 3 > 4 ]; echo $?     # 0 (true, string comparison)
[[ 3 > 4 ]]; echo $?   # 1 (false, arithmetic comparison)
</code>

The double‑bracket

[[

construct behaves more like C‑style expressions and avoids some pitfalls of

[

.

Using [[ ]]

[[

is a keyword, not an external command, and its syntax is closer to C‑family languages. It supports string pattern matching and unary operators:

<code>[[ (-d "$HOME") && (-w "$HOME") ]] && echo 'home is a writable directory'
[[ "abc def .d,x--" == a[abc]*\ ?d* ]]; echo $?   # 0
[[ "abc def c" == a[abc]*\ ?d* ]]; echo $?      # 1
</code>

Common unary operators

-z

: test for empty string

-n

: test for non‑empty string

-d

: directory exists

-e

: file exists

-f

: regular file

-r

: readable

-w

: writable

-N

: modified since last read

Arithmetic evaluation with (( ))

The double‑parenthesis construct is primarily for arithmetic evaluation. Its exit status follows the convention that a result of zero is considered false (exit code 1) and any non‑zero result is true (exit code 0).

<code>(( 0 )); echo $?   # 0 (true)
(( 3 > 4 )); echo $? # 0 (true because expression evaluates to 0)
(( 0 && 1 )); echo $? # 0
(( 0 || 1 )); echo $? # 1
(( 100 && 11 )); echo $? # 1
</code>

References

http://www.ibm.com/developerworks/cn/linux/l-bash-test.html

http://tldp.org/LDP/abs/html/testconstructs.html

http://tldp.org/LDP/abs/html/dblparens.html

unixbashshell scriptingtest commandconditional expressions
Tencent IMWeb Frontend Team
Written by

Tencent IMWeb Frontend Team

IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.