Theory
What is inside those brackets?
You have written if [ $n -lt 5 ] without really asking what the [ ] is. Here is the surprise: the square brackets are a command, called test. [ $n -lt 5 ] runs the test command, which checks the condition and returns success or failure, exactly the exit status that if and && rely on.
So mastering conditions means mastering test. It checks three kinds of things: files, numbers, and strings. This lesson lays out all three, and the syntax rules that catch beginners.
At a glance
| Kind | Operators | Example |
|---|---|---|
| File | -e exists, -f regular file, -d directory, -r/-w/-x readable/writable/executable | [ -f notes.txt ] |
| Numeric | -eq equal, -ne not equal, -lt, -le, -gt, -ge | [ $n -gt 3 ] |
| String | = equal, != not equal, -z empty, -n non-empty | [ "$a" = "$b" ] |
Practical
Testing files, numbers, and strings (verified)
$ [ -f real.txt ] && echo "it is a regular file"
it is a regular file
$ [ -d demo ] && echo "demo is a directory"
demo is a directory
$ [ 5 -gt 3 ] && echo "5 is greater than 3"
5 is greater than 3
$ [ "abc" = "abc" ] && echo "strings equal"
strings equal
$ [ -z "" ] && echo "empty string"
empty stringWatch out
Numbers use -eq, strings use = , and mind the spaces
Two rules save endless grief. First, use the right operators for the type: compare NUMBERS with -eq -ne -lt -le -gt -ge, and compare STRINGS with = != -z -n. Writing [ $n = 5 ] compares as strings, and [ "$a" -eq "$b" ] on text is an error. Match the operator to the data.
Second, spaces are mandatory inside the brackets and around the operator: [ $n -lt 5 ] works, but [$n -lt 5] or [ $n -lt5 ] fails, because [ is a command and needs its arguments separated. These two mistakes account for most broken shell conditions.
Quiz
You want to check whether the number in variable n equals 10. Which test is correct?
- [ $n = 10 ], using = for the comparison
- [ $n -eq 10 ], using the numeric-equality operator -eq
- [$n -eq 10], packed tightly without spaces
- [ $n == equal 10 ]
Show the answer
[ $n -eq 10 ], using the numeric-equality operator -eq
Numbers are compared with the numeric operators, and equality is -eq, so [ $n -eq 10 ] is correct. Option A uses =, which is the STRING equality operator; it may appear to work for simple cases but is the wrong tool for numeric comparison and behaves differently (for example, it would treat '10' and '010' as different strings though they are numerically equal). Option C omits the required SPACES: [ is a command and needs its arguments separated, so [$n must be [ $n. Option D is invented syntax. Remember: -eq for numbers, = for strings, and always put spaces inside the brackets.
Think first
Why are numeric and string equality different operators?
Why does the shell insist on -eq for numbers and = for strings, instead of one equals for everything? Then tap.
Show the answer
Because comparing as NUMBERS and comparing as TEXT can give different answers, so the shell makes you say which you mean. Everything in the shell starts life as text, and as text, '10' and '010' and ' 10 ' are three DIFFERENT strings, but as numbers they are all equal to ten. If you use -eq, the shell interprets both sides as integers and compares their VALUES, so [ 10 -eq 010 ] is true. If you use =, it compares the raw CHARACTERS, so [ 10 = 010 ] is false because the strings differ. Neither is 'right' in general; it depends on whether you care about numeric value or exact text. By providing separate operators, the shell lets you be explicit and avoids silently guessing wrong. This matters in real scripts: comparing a user's typed input, a version number, or a count behaves differently depending on which you choose. The discipline is simple and worth building early: if the thing is a number and you care about its value, use -eq and its numeric siblings; if it is text and you care about the exact characters, use = and !=. Choosing the right comparison prevents subtle, hard-to-spot bugs.
Summary
Key takeaways
- The [ ] in an if statement is really the test command, which returns success or failure for a condition.
- File tests: -e exists, -f regular file, -d directory, -r/-w/-x readable/writable/executable.
- Numeric comparison: -eq, -ne, -lt, -le, -gt, -ge.
- String comparison: = equal, != not equal, -z empty (zero-length), -n non-empty.
- Use numeric operators for numbers and string operators for strings; mixing them causes wrong results or errors.
- Spaces are mandatory inside the brackets and around operators: [ $n -lt 5 ], not [$n -lt5].
- Memory hook: test checks files (-f/-d), numbers (-eq/-lt), strings (=); spaces required.