Shell Test Blocks
[ is defined by the POSIX standard and thus it’s supported by all POSIX
shells. On the other hand, although [[ is more powerful it only works with
bash, zsh and ksh.
Initially
[was implemented as a command (/usr/bin/[). Because of that, the expression needs to be surrounded by spaces:[ expr ]and[[ expr ]].
Differences
| Feature | [ ... ] old style |
[[ ... ]] new style |
Comments |
|---|---|---|---|
| Variable expansion | "$v" |
$v |
New style will not split the variable if it contains spaces. |
| String comparison | = |
= or == |
|
!= |
!= |
||
\> and \< |
> and < |
||
| Integer comparison | -ge, -le, -eq |
-gt, -lt, -eq |
No differences. |
-gt, -lt, -ne |
-gt, -lt, -eq |
||
| Logical operators | Deprecated by POSIX | && and || |
See below. |
| Grouping | Deprecated by POSIX | ( and ) |
See below. |
| Glob matching | Not available | [[ $v == *.txt ]] |
|
| Regex matching | Not available | [[ $v =~ .*\.txt ]] |
POSIX deprecates -a, -o, \( and \). So instead of using:
if [ -f file1 -a \( "$var1" -eq 0 -i "$var2" -eq 0 \) ]; then
echo true
fiIt’s necessary to use:
if [ -f file1 ] && { [ "$var1" -eq 0 ] || [ "$var2" -eq 0 ]; }; then
echo true
fiWhile that could be written in the following way with [[:
if [[ -f file 1 && ( $var1 -eq 0 || $var2 -eq 0 ) ]]; then
echo true
fiBesides the differences above,
[might also lack the following operators depending on the implementation:-e,-nt(newer than),-ot(older than),-ef(exact same file) and!(not).
Arithmetic Expansion
(( ... )) and $(( ... )) can be used for integer comparison and arithmetic
operations.
Examples:
# POSIX sh
i=$((j + 3))
lvcreate -L "$((24 * 1024))" -n lv99 vg99
q=$((29 / 6)) r=$((29 % 6))
if test "$((a%4))" = 0; then echo "true"; fi
# Bash
((a=$a+7)) # Add 7 to a
((a = a + 7)) # Add 7 to a. Identical to the previous command.
((a += 7)) # Add 7 to a. Identical to the previous command.
if ((a > 5)); then echo "a is more than 5"; fi
true; echo "$?" # Writes 0, because a successful command returns 0.
((10 > 6)); echo "$?" # Also 0. An arithmetic command returns 0 for true.
echo "$((10 > 6))" # Writes 1. An arithmetic expression evaluates to 1 for true.
for ((i=0, j=0; i<100; i++, j+=5)); do echo "$i"; doneUnlike
[and[[, expressions do not need to be surrounded by spaces with$((expr))and((expr)).