Bash error: "integer expression expected"

The Bash "integer expression expected" error happens when -eq/-lt/-gt/-le/-ge are used with a value that contains non-digits or is empty.

Error String

bash: [: VAR: integer expression expected

Tldr

Numeric test operators like -eq, -lt, -gt require both sides to parse as integers. Empty strings or non-numeric values trigger this error. Validate or default the variable before the test.

Cause

Bash treats unset/empty variables as the empty string, which is not a number. Operators -eq/-ne/-lt/-le/-gt/-ge then abort. The same happens when input came from a command that produced non-numeric output (a header line, a trailing space, or "N/A").

Repro

#!/usr/bin/env bash
count=
if [ "$count" -gt 0 ]; then         # error: empty is not an integer
  echo "many"
fi

Fix

#!/usr/bin/env bash
count=${count:-0}                    # default to 0 when empty
if [ "$count" -gt 0 ]; then
  echo "many"
fi

# Or use (( )) which treats empty as 0:
if (( count > 0 )); then
  echo "many"
fi

Explanation

The `(( ))` arithmetic form is more forgiving: it auto-coerces unset/empty to 0 and supports the familiar > < == operators without quoting.

Faq

Q

Why does my variable look like a number but still fail?

A

A trailing newline or space from command substitution counts as non-numeric. Strip with `${var//[^0-9]/}` or trim with `${var##[[:space:]]}`.

Q

Why does -eq fail on "5\n"?

A

The trailing newline makes the value non-numeric to the test builtin; strip it before comparing.

Q

How do I compare version numbers?

A

Use `sort -V` and compare the result, or split on dots and compare components numerically.

Deep Dive

Heading

Numeric operators need numeric operands

Body

`-eq`, `-ne`, `-lt`, `-le`, `-gt` and `-ge` parse both sides as integers. Anything else — an empty value, a decimal such as `1.5`, a number with a trailing newline from command substitution, or a word — produces this error. Command output is the usual source: `wc -l file` prints the filename too, so use `wc -l < file`. Trim stray whitespace with `${var//[[:space:]]/}` before comparing.

Heading

Comparing decimals and strings

Body

Bash has no floating-point comparison. For decimals use `awk "BEGIN{exit !($a > $b)}"` or `bc -l`, both of which handle fractions correctly. For strings, use `=` and `!=` (or `==` inside `[[ ]]`) rather than `-eq`, which would try to parse them as numbers. Validate external input with `[[ $n =~ ^-?[0-9]+$ ]]` before any numeric test so a malformed value produces your error message instead of a shell diagnostic.

Checklist

Print the operand with `printf "[%s]"` to reveal whitespace or emptiness.

Use `wc -l < file` so the filename is not included.

Validate with a regex before numeric comparison.

Use `awk` or `bc` for decimals, and `=`/`!=` for strings.