Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Exit Codes and Conditionals  ›  Lesson

if and the [[ ]] Test

if 15 minif runs a command and takes the then branch when its exit status is zero, and the [[ ]] test compares strings, numbers and files.

if and the [[ ]] Test

Run backup.sh with no argument and it happily archives an empty path. Run it with a typo and tar fails halfway. A careful script checks its input first and refuses politely. That needs a way to choose between actions.

The rule

if runs a command; status zero takes the then branch.

if [[ $# -lt 1 ]]; then
    echo "Usage: $0 SOURCE [NAME]" >&2
    exit 2
fi

src="$1"
if [[ ! -d "$src" ]]; then
    echo "Not a folder: $src" >&2
    exit 1
elif [[ ! -r "$src" ]]; then
    echo "Cannot read: $src" >&2
    exit 1
else
    echo "Backing up $src"
fi

(>&2 sends a message to standard error, so it does not mix with real output.)

if does not test "true or false" in the abstract. It runs a command and looks at its exit status. [[ ... ]] is simply a command whose status is 0 when the test inside holds. So any command works:

if tar -czf "$archive" "$src"; then echo "Saved"; fi
if grep -q ERROR log.txt; then echo "Errors found"; fi

The tests you will use most inside [[ ]]:

Kind Operators
Strings == != equal, not equal; -z empty; -n not empty
Numbers -eq -ne -lt -le -gt -ge
Files -e exists, -f regular file, -d directory, -r -w -x readable, writable, executable, -s not empty
Negation ! in front of a test

For numbers you can also use arithmetic: if (( count > 10 )); then. Older scripts use single brackets [ ... ], which work in any POSIX shell but are fussier: variables must be quoted inside them.

The shortcut

Match the operator family to the data: letters for numbers in [[ ]] (-lt, -eq), symbols for text (==, <), dashes plus a letter for files (-d). A symbol like > inside [[ ]] compares dictionary order, not size.

Why [[ 10 > 9 ]] is falseStep 1 of 4
  1. Which family?

    > is a symbol, so this is a text comparison.

The other classic mistake is missing spaces. [[ is a word of its own, so [[$x == y]] fails with a "command not found" error.

Drills

Answer fast — trust the rule.

quick drill

Does [[ 10 > 9 ]] succeed?

quick drill

Which test is true when $src is an existing directory?

quick drill

When does if grep -q ERROR log.txt; then ... run its then branch?

quick drill

What happens with if [[$x == y]]; then?

quick drill

Which test is true when the variable name is empty?

Remember

  • if runs a command; status zero takes the then branch.
  • Match the family: -lt for numbers, == and < for text, -d for files.
  • Trap: > in [[ ]] is dictionary order; spaces around [[ and ]] are required.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainRefuse bad input

Add two guards to the top of backup.sh: stop with status 2 and a usage message if no argument was given, and stop with status 1 if the argument is not a directory. Write the code and explain how if decides which branch to run and why you chose each test operator.