Linux CLI 60 ๐ง test command in shell scripts
#!/bin/bash
# Numeric comparison
a=5
b=10
if test $a -lt $b; then
echo "$a is less than $b"
fi
# String comparison
str1="hello"
str2="world"
if [ "$str1" != "$str2" ]; then
echo "Strings are not equal"
fi
# File test
if test -f /etc/passwd; then
echo "/etc/passwd is a regular file"
fi
# Logical AND
if test $a -eq 5 && $b -eq 10; then
echo "Both conditions are true"
fi
# String length
str="Alibaba Cloud"
if [ -n "$str" ]; then
echo "String is not empty"
fi
The test command is the engine behind every if condition you’ve written so far. [ ... ] is actually a synonym for test โ they do exactly the same thing. Understanding test directly makes your scripts clearer and helps you avoid quoting bugs.
Key point: test evaluates a conditional expression and returns an exit status โ 0 for true, 1 for false. [ ... ] is the same command with a required closing bracket. [[ ... ]] is bash’s extended version with more features.
a – test command part 1
test is used to evaluate conditional expressions. It returns an exit status based on whether the expression evaluates to true or false. It can be used in if statements, loops, and case statements.
Syntax:
test EXPRESSION
[ EXPRESSION ]
Both forms are identical. [ is literally a command โ /usr/bin/[ โ that requires a closing ].
Common uses:
| Category | Operators |
|---|---|
| Numeric comparison | -eq, -ne, -lt, -le, -gt, -ge |
| String comparison | =, != |
| File tests | -e, -f, -d, -r, -w, -x |
| Logical operators | !, -a, -o, &&, || |
| String length | -z, -n |
Numeric comparisons:
| Operator | Meaning |
|---|---|
-eq | Equal |
-ne | Not equal |
-lt | Less than |
-le | Less than or equal |
-gt | Greater than |
-ge | Greater than or equal |
a=5
b=10
if test $a -lt $b; then
echo "$a is less than $b"
fi
[ 5 is less than 10 ]
if [ $a -eq 5 ]; then
echo "a is 5"
fi
[ a is 5 ]
if [ $b -ge 10 ]; then
echo "b is at least 10"
fi
[ b is at least 10 ]
String comparisons:
| Operator | Meaning |
|---|---|
= | Equal |
!= | Not equal |
< | Less than (ASCII) |
> | Greater than (ASCII) |
str1="hello"
str2="world"
if [ "$str1" != "$str2" ]; then
echo "Strings are not equal"
fi
[ Strings are not equal ]
if [ "$str1" = "hello" ]; then
echo "Match"
fi
[ Match ]
test vs [ ] vs [[ ]]:
| Form | Example | Notes |
|---|---|---|
test | test -f file | POSIX, no brackets |
[ ] | [ -f file ] | POSIX, needs spaces |
[[ ]] | [[ -f file ]] | Bash only, more features |
All three do the same basic thing:
test -f /etc/passwd && echo "yes"
[ -f /etc/passwd ] && echo "yes"
[[ -f /etc/passwd ]] && echo "yes"
Checking the result directly:
$ test 5 -lt 10
$ echo $?
[ 0 ]
$ test 5 -gt 10
$ echo $?
[ 1 ]
test doesn’t print anything โ it just sets $?.
Using test with && and ||:
$ test -f /etc/passwd && echo "exists" || echo "missing"
[ exists ]
$ test -d /etc/passwd && echo "dir" || echo "not a dir"
[ not a dir ]
Why use test instead of [ ]?
- Slightly clearer in some scripts (no brackets to balance)
- Useful when
[conflicts with glob characters - Shows what’s really happening โ
[is just a command
Why use [ ] instead?
- More readable โ looks like a condition
- The standard idiom in shell scripting
- Works identically
Tip: Use
[ ]for readability in most scripts. Know thattestexists so you understand what[really is.
Spaces matter:
# โ
Correct
[ -f file ]
test -f file
# โ Wrong โ [ is a command, needs spaces
[-f file] # "command not found: [-f"
[ -f file] # missing closing ]
b – test command part 2
File tests:
| Operator | True if |
|---|---|
-e FILE | File exists |
-f FILE | Regular file |
-d FILE | Directory |
-r FILE | Readable |
-w FILE | Writable |
-x FILE | Executable |
-s FILE | Non-empty |
-L FILE | Symlink |
-p FILE | Named pipe |
-S FILE | Socket |
-b FILE | Block device |
-c FILE | Character device |
Examples:
# Exists
if test -e /etc/passwd; then
echo "exists"
fi
[ exists ]
# Regular file
if test -f /etc/passwd; then
echo "/etc/passwd is a regular file"
fi
[ /etc/passwd is a regular file ]
# Directory
if test -d /etc; then
echo "/etc is a directory"
fi
[ /etc is a directory ]
# Readable
if test -r /etc/passwd; then
echo "readable"
fi
[ readable ]
# Writable
if test -w /tmp; then
echo "writable"
fi
[ writable ]
# Executable
if test -x /usr/bin/ls; then
echo "executable"
fi
[ executable ]
# Non-empty
if test -s /etc/passwd; then
echo "non-empty"
fi
[ non-empty ]
File comparison operators:
| Operator | True if |
|---|---|
FILE1 -nt FILE2 | FILE1 is newer than FILE2 |
FILE1 -ot FILE2 | FILE1 is older than FILE2 |
FILE1 -ef FILE2 | Same file (same inode) |
if [ file1.txt -nt file2.txt ]; then
echo "file1 is newer"
fi
if [ /etc/passwd -ef /etc/passwd ]; then
echo "same file"
fi
Logical operators:
| Operator | Meaning | Status |
|---|---|---|
! | NOT | Current |
-a | AND | Deprecated |
-o | OR | Deprecated |
&& | AND | Preferred |
|| | OR | Preferred |
# NOT
if [ ! -f /nonexistent ]; then
echo "File not found"
fi
[ File not found ]
# AND (deprecated inside [ ])
if [ -f /etc/passwd -a -r /etc/passwd ]; then
echo "exists and readable"
fi
# AND (preferred โ separate tests)
if [ -f /etc/passwd ] && [ -r /etc/passwd ]; then
echo "exists and readable"
fi
[ exists and readable ]
# OR
if [ -f /etc/hosts ] || [ -f /etc/passwd ]; then
echo "at least one exists"
fi
[ at least one exists ]
โ ๏ธ Warning:
-aand-oare deprecated and ambiguous when mixed with file tests. Use&&and||between separate[ ]blocks, or switch to[[ ]].
In [[ ]], combine inside:
if [[ -f /etc/passwd && -r /etc/passwd ]]; then
echo "exists and readable"
fi
String length operators:
| Operator | True if |
|---|---|
-z STRING | String is null (zero length) |
-n STRING | String is not null |
str="Alibaba Cloud"
if [ -n "$str" ]; then
echo "String is not empty"
fi
[ String is not empty ]
empty=""
if [ -z "$empty" ]; then
echo "String is empty"
fi
[ String is empty ]
Always quote strings with -z and -n:
# โ
Correct
[ -z "$var" ]
[ -n "$var" ]
# โ Wrong โ breaks if $var is empty or has spaces
[ -z $var ]
[ -n $var ]
Checking multiple things at once:
# File exists AND is readable
if [ -f "$file" ] && [ -r "$file" ]; then
echo "Can read $file"
fi
# Directory OR file
if [ -d "$path" ] || [ -f "$path" ]; then
echo "Path exists"
fi
# NOT empty AND NOT a directory
if [ -n "$name" ] && [ ! -d "$name" ]; then
echo "Valid name"
fi
The square brackets [ ] vs test:
They are the same command. [ is a symlink to test that expects a closing ]:
$ ls -l /usr/bin/[
lrwxrwxrwx 1 root root 4 ... /usr/bin/[ -> test
$ test -f /etc/passwd; echo $?
[ 0 ]
$ [ -f /etc/passwd ]; echo $?
[ 0 ]
[ ] vs [[ ]] โ a quick reminder:
| Feature | [ ] / test | [[ ]] |
|---|---|---|
| POSIX | โ | โ |
| Quote variables | Required | Optional |
&& / || inside | โ | โ |
Regex =~ | โ | โ |
Glob == | โ | โ |
| Word splitting | Yes | No |
< / > | Escape needed | Works bare |
# [ ] โ quote everything
if [ "$name" = "Alice" ]; then ...; fi
# [[ ]] โ no quoting needed
if [[ $name == "Alice" ]]; then ...; fi
# [[ ]] โ logical operators inside
if [[ $a -gt 0 && $b -gt 0 ]]; then ...; fi
# [[ ]] โ regex
if [[ $email =~ @.*\.com$ ]]; then ...; fi
Complete expression reference:
| Category | Expression | Meaning |
|---|---|---|
| Numeric | $a -eq $b | Equal |
| Numeric | $a -ne $b | Not equal |
| Numeric | $a -lt $b | Less than |
| Numeric | $a -le $b | Less or equal |
| Numeric | $a -gt $b | Greater than |
| Numeric | $a -ge $b | Greater or equal |
| String | $a = $b | Equal |
| String | $a != $b | Not equal |
| String | -z $a | Empty |
| String | -n $a | Non-empty |
| File | -e $f | Exists |
| File | -f $f | Regular file |
| File | -d $f | Directory |
| File | -r $f | Readable |
| File | -w $f | Writable |
| File | -x $f | Executable |
| File | -s $f | Non-empty |
| File | -L $f | Symlink |
| Compare | $f1 -nt $f2 | Newer than |
| Compare | $f1 -ot $f2 | Older than |
| Compare | $f1 -ef $f2 | Same file |
| Logic | ! EXPR | NOT |
| Logic | EXPR1 && EXPR2 | AND |
| Logic | EXPR1 || EXPR2 | OR |
Complete Example Session
# ============================================
# PART 1: NUMERIC COMPARISON
# ============================================
$ a=5
$ b=10
$ if test $a -lt $b; then echo "$a < $b"; fi
[ 5 < 10 ]
$ if test $a -eq 5; then echo "a is 5"; fi
[ a is 5 ]
$ test 5 -gt 10
$ echo $?
[ 1 ]
# ============================================
# PART 2: STRING COMPARISON
# ============================================
$ str1="hello"
$ str2="world"
$ if [ "$str1" != "$str2" ]; then echo "not equal"; fi
[ not equal ]
$ if [ "$str1" = "hello" ]; then echo "match"; fi
[ match ]
# ============================================
# PART 3: FILE TESTS
# ============================================
$ if test -f /etc/passwd; then echo "regular file"; fi
[ regular file ]
$ if test -d /etc; then echo "directory"; fi
[ directory ]
$ if test -r /etc/passwd; then echo "readable"; fi
[ readable ]
$ if test -x /usr/bin/ls; then echo "executable"; fi
[ executable ]
$ if test -s /etc/passwd; then echo "non-empty"; fi
[ non-empty ]
# ============================================
# PART 4: LOGICAL AND
# ============================================
$ a=5
$ b=10
$ if test $a -eq 5 && $b -eq 10; then echo "both true"; fi
[ both true ]
$ if [ $a -gt 0 ] && [ $b -gt 0 ]; then echo "both positive"; fi
[ both positive ]
# ============================================
# PART 5: LOGICAL OR
# ============================================
$ if [ -f /etc/hosts ] || [ -f /etc/passwd ]; then echo "one exists"; fi
[ one exists ]
# ============================================
# PART 6: LOGICAL NOT
# ============================================
$ if [ ! -f /nonexistent ]; then echo "not found"; fi
[ not found ]
# ============================================
# PART 7: STRING LENGTH
# ============================================
$ str="Alibaba Cloud"
$ if [ -n "$str" ]; then echo "not empty"; fi
[ not empty ]
$ empty=""
$ if [ -z "$empty" ]; then echo "empty"; fi
[ empty ]
# ============================================
# PART 8: TEST VS [ ] VS [[ ]]
# ============================================
$ test -f /etc/passwd && echo "yes"
[ yes ]
$ [ -f /etc/passwd ] && echo "yes"
[ yes ]
$ [[ -f /etc/passwd ]] && echo "yes"
[ yes ]
# ============================================
# PART 9: REGEX WITH [[ ]]
# ============================================
$ email="user@example.com"
$ if [[ $email =~ @.*\.com$ ]]; then echo "valid"; fi
[ valid ]
# ============================================
# PART 10: GLOB PATTERN WITH [[ ]]
# ============================================
$ file="report.txt"
$ if [[ $file == *.txt ]]; then echo "text file"; fi
[ text file ]
# ============================================
# PART 11: NUMERIC WITH [[ ]]
# ============================================
$ a=5
$ b=10
$ if [[ $a -lt $b ]]; then echo "less"; fi
[ less ]
$ if [[ $a -lt $b && $b -eq 10 ]]; then echo "both"; fi
[ both ]
# ============================================
# PART 12: FILE COMPARISON
# ============================================
$ touch /tmp/old.txt
$ sleep 1
$ touch /tmp/new.txt
$ if [ /tmp/new.txt -nt /tmp/old.txt ]; then echo "new is newer"; fi
[ new is newer ]
# ============================================
# PART 13: COMBINED CONDITIONS
# ============================================
$ file="/etc/passwd"
$ if [ -f "$file" ] && [ -r "$file" ]; then
> echo "Can read $file"
> fi
[ Can read /etc/passwd ]
# ============================================
# PART 14: NEGATION WITH FILES
# ============================================
$ if [ ! -d /nonexistent ]; then
> echo "not a directory"
> fi
[ not a directory ]
# ============================================
# PART 15: FULL SCRIPT EXAMPLE
# ============================================
$ cat > check.sh << 'EOF'
#!/bin/bash
a=5
b=10
if test $a -lt $b; then
echo "$a is less than $b"
fi
str1="hello"
str2="world"
if [ "$str1" != "$str2" ]; then
echo "Strings are not equal"
fi
if test -f /etc/passwd; then
echo "/etc/passwd is a regular file"
fi
if test $a -eq 5 && $b -eq 10; then
echo "Both conditions are true"
fi
str="Alibaba Cloud"
if [ -n "$str" ]; then
echo "String is not empty"
fi
EOF
$ chmod +x check.sh
$ ./check.sh
[ 5 is less than 10 ]
[ Strings are not equal ]
[ /etc/passwd is a regular file ]
[ Both conditions are true ]
[ String is not empty ]
Quick Reference
test / [ ] / [[ ]]
| Form | Example | Portability |
|---|---|---|
test | test -f file | POSIX |
[ ] | [ -f file ] | POSIX |
[[ ]] | [[ -f file ]] | Bash, ksh, zsh |
Numeric Operators
| Operator | Meaning |
|---|---|
-eq | Equal |
-ne | Not equal |
-lt | Less than |
-le | Less than or equal |
-gt | Greater than |
-ge | Greater than or equal |
String Operators
| Operator | Meaning |
|---|---|
= | Equal |
!= | Not equal |
-z | Empty |
-n | Non-empty |
< | Less (ASCII) |
> | Greater (ASCII) |
File Tests
| Operator | True if |
|---|---|
-e | Exists |
-f | Regular file |
-d | Directory |
-r | Readable |
-w | Writable |
-x | Executable |
-s | Non-empty |
-L | Symlink |
-p | Named pipe |
-S | Socket |
File Comparison
| Operator | True if |
|---|---|
f1 -nt f2 | f1 newer than f2 |
f1 -ot f2 | f1 older than f2 |
f1 -ef f2 | Same file |
Logical Operators
| Operator | Meaning | Status |
|---|---|---|
! | NOT | Current |
-a | AND | Deprecated |
-o | OR | Deprecated |
&& | AND | Preferred |
|| | OR | Preferred |
[ ] vs [[ ]
| Feature | [ ] | [[ ]] |
|---|---|---|
| POSIX | โ | โ |
| Quote vars | Required | Optional |
&& inside | โ | โ |
|| inside | โ | โ |
Regex =~ | โ | โ |
Glob == | โ | โ |
</> | Escape | Bare |
Best Practices
โ Do This:
# Quote variables in [ ]
if [ "$name" = "Alice" ]; then ...; fi # โ
# Use -z and -n with quotes
if [ -z "$var" ]; then ...; fi # โ
if [ -n "$var" ]; then ...; fi # โ
# Separate tests with &&
if [ -f "$f" ] && [ -r "$f" ]; then ...; fi # โ
# Use [[ ]] in bash
if [[ $name == "Alice" ]]; then ...; fi # โ
# Combine inside [[ ]]
if [[ -f "$f" && -r "$f" ]]; then ...; fi # โ
# Use test for simple checks
test -f file && echo "ok" # โ
# Use -n instead of bare string
if [ -n "$str" ]; then ...; fi # โ
# Use ! for negation
if [ ! -f "$f" ]; then ...; fi # โ
โ Don’t Do This:
# Don't forget spaces
[-f file] # โ command not found
[ -f file] # โ missing ]
# Don't use -a and -o
[ -f file -a -r file ] # โ ๏ธ deprecated
[ -f file ] && [ -r file ] # โ
# Don't leave strings unquoted
[ -z $var ] # โ breaks on empty
[ -z "$var" ] # โ
# Don't use = for numbers
[ "$a" = 5 ] # โ ๏ธ string compare
[ "$a" -eq 5 ] # โ
# Don't use -eq for strings
[ "$name" -eq "Alice" ] # โ error
[ "$name" = "Alice" ] # โ
# Don't use > without escaping in [ ]
[ "$a" > "$b" ] # โ redirection
[[ "$a" > "$b" ]] # โ
# Don't test a variable without quotes
if [ $name = "" ]; then ...; fi # โ breaks if unset
if [ -z "$name" ]; then ...; fi # โ
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
| Missing spaces | command not found | [ -f file ] |
Missing ] | Syntax error | Add closing bracket |
| Unquoted variable | Breaks on empty | Quote: "$var" |
-a / -o | Deprecated | Use && / || |
= for numbers | String compare | Use -eq |
-eq for strings | Error | Use = |
> unescaped | Redirection | \> or [[ ]] |
test with [[ features | Not supported | Use [[ ]] |
Real-World Examples
1. Numeric Comparison
#!/bin/bash
a=5
b=10
if test $a -lt $b; then
echo "$a is less than $b"
fi
[ 5 is less than 10 ]
2. String Comparison
#!/bin/bash
str1="hello"
str2="world"
if [ "$str1" != "$str2" ]; then
echo "Strings are not equal"
fi
[ Strings are not equal ]
3. File Test
#!/bin/bash
if test -f /etc/passwd; then
echo "/etc/passwd is a regular file"
fi
[ /etc/passwd is a regular file ]
4. Logical AND
#!/bin/bash
a=5
b=10
if test $a -eq 5 && $b -eq 10; then
echo "Both conditions are true"
fi
[ Both conditions are true ]
5. String Length
#!/bin/bash
str="Alibaba Cloud"
if [ -n "$str" ]; then
echo "String is not empty"
fi
[ String is not empty ]
6. Check If File Exists
#!/bin/bash
file="$1"
if [ ! -f "$file" ]; then
echo "Error: $file not found" >&2
exit 1
fi
echo "File exists"
7. Check If Directory
#!/bin/bash
dir="$1"
if [ -d "$dir" ]; then
echo "Directory exists"
else
echo "Not a directory"
fi
8. Check Readability
#!/bin/bash
if [ -r "$1" ]; then
cat "$1"
else
echo "Cannot read $1" >&2
exit 1
fi
9. Check Executability
#!/bin/bash
if [ ! -x "$1" ]; then
echo "$1 is not executable" >&2
exit 1
fi
"$1"
10. Empty Variable Check
#!/bin/bash
if [ -z "$1" ]; then
echo "Usage: $0 <arg>" >&2
exit 1
fi
echo "Arg: $1"
11. Non-Empty Variable Check
#!/bin/bash
read -p "Name: " name
if [ -n "$name" ]; then
echo "Hello, $name"
else
echo "No name entered"
fi
12. Both File AND Readable
#!/bin/bash
file="/etc/passwd"
if [ -f "$file" ] && [ -r "$file" ]; then
echo "Can read $file"
head -3 "$file"
fi
13. Either File OR Backup
#!/bin/bash
if [ -f config.txt ] || [ -f config.bak ]; then
echo "Config found"
else
echo "No config"
fi
14. File Newer Than
#!/bin/bash
if [ "$1" -nt "$2" ]; then
echo "$1 is newer than $2"
else
echo "$1 is older or same"
fi
15. Same File Check
#!/bin/bash
if [ "$1" -ef "$2" ]; then
echo "Same file"
else
echo "Different files"
fi
16. Regex Email Validation
#!/bin/bash
read -p "Email: " email
if [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "Valid email"
else
echo "Invalid email"
fi
17. Glob Pattern Match
#!/bin/bash
file="report.txt"
if [[ "$file" == *.txt ]]; then
echo "Text file"
fi
18. Numeric Range
#!/bin/bash
read -p "Age: " age
if [[ "$age" -ge 18 && "$age" -le 65 ]]; then
echo "Working age"
else
echo "Outside range"
fi
19. Multiple File Checks
#!/bin/bash
for f in /etc/passwd /etc/hosts /etc/group; do
if [ -f "$f" ]; then
echo "โ $f"
else
echo "โ $f"
fi
done
20. Validate Numeric Input
#!/bin/bash
read -p "Number: " n
if [[ "$n" =~ ^-?[0-9]+$ ]]; then
echo "Valid integer"
else
echo "Not an integer"
fi
Visual: test / [ ] / [[ ]
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ test COMMAND โ
โ โ
โ test -f /etc/passwd โ
โ โ โ
โ โโโโ returns 0 (true) or 1 (false) โ
โ โ
โ No output โ just exit status โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ [ ] โ same as test โ
โ โ
โ [ -f /etc/passwd ] โ
โ โ โ โ
โ โโโโ command โโโโโโโ โ
โ โ
โ [ is a real command that requires ] โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ [[ ]] โ bash extended โ
โ โ
โ [[ -f /etc/passwd && -r /etc/passwd ]] โ
โ โ
โ โข No quoting needed โ
โ โข && and || work inside โ
โ โข Regex with =~ โ
โ โข Glob with == โ
โ โข Bash only โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Visual: test Categories
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ test categories โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ NUMERIC โ โ
โ โ -eq -ne -lt -le -gt -ge โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ STRING โ โ
โ โ = != -z -n < > โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ FILE โ โ
โ โ -e -f -d -r -w -x -s -L โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ FILE COMPARE โ โ
โ โ -nt -ot -ef โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ LOGICAL โ โ
โ โ ! -a -o && || โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Concept | Syntax | Example |
|---|---|---|
| test | test EXPR | test -f file |
| Bracket form | [ EXPR ] | [ -f file ] |
| Extended form | [[ EXPR ]] | [[ -f file ]] |
| Numeric equal | -eq | [ $a -eq 5 ] |
| Numeric not equal | -ne | [ $a -ne 5 ] |
| Numeric less | -lt | [ $a -lt 5 ] |
| Numeric less or equal | -le | [ $a -le 5 ] |
| Numeric greater | -gt | [ $a -gt 5 ] |
| Numeric greater or equal | -ge | [ $a -ge 5 ] |
| String equal | = | [ "$a" = "$b" ] |
| String not equal | != | [ "$a" != "$b" ] |
| String empty | -z | [ -z "$s" ] |
| String non-empty | -n | [ -n "$s" ] |
| File exists | -e | [ -e file ] |
| Regular file | -f | [ -f file ] |
| Directory | -d | [ -d dir ] |
| Readable | -r | [ -r file ] |
| Writable | -w | [ -w file ] |
| Executable | -x | [ -x file ] |
| Non-empty file | -s | [ -s file ] |
| Symlink | -L | [ -L link ] |
| Newer than | -nt | [ f1 -nt f2 ] |
| Older than | -ot | [ f1 -ot f2 ] |
| Same file | -ef | [ f1 -ef f2 ] |
| NOT | ! | [ ! -f f ] |
| AND | && | [ -f f ] && [ -r f ] |
| OR | || | [ -f f ] || [ -f g ] |
Key takeaways:
testevaluates a condition and returns an exit status โ0for true,1for false[ ... ]is the same astestโ just more readable[[ ... ]]is bash’s extended version with&&,||, regex, and glob matching- Use numeric operators (
-eq,-lt, etc.) for numbers - Use string operators (
=,!=,-z,-n) for strings - Use file operators (
-f,-d,-r,-x) to test files - Quote variables in
[ ]โ unquoted empties cause errors - Use
&&and||between separate[ ]blocks โ avoid deprecated-aand-o - Use
!to negate a condition - Combine multiple tests with
&&(and) and||(or) - Prefer
[[ ]]in bash when you need regex or logical operators inside - Spaces matter โ
[ -f file ]not[-f file] testreturns a status, not output โ check it with$?or use it inif
Remember: test is the engine behind every if you’ve written. [ is just another name for it. Learn the operators by category โ numeric, string, file, logical โ and you’ll never fumble a condition again. Quote your variables,prefer [[ ]] in bash, and use &&/|| instead of -a/-o. Master test, and every decision your script makes becomes clear and correct.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!