When do you use (( )) or /usr/bin/test
You use /usr/bin/test
when you want things to run more slowly. Modern shells (most shells released since about 1990, probably earlier) have test
and its synonym [
as built-in commands. Formally invoking /usr/bin/test
would be an act of desparation because the shell has a broken test command and the system standalone is OK - but it would be better to get a fixed shell.
You use (( ... ))
to do arithmetic. The old-fashioned alternative was the expr
command. That was tricky to use because it required a lot of escaping - it is/was a separate executable, and you had to get lots of shell metacharacters past the shell to expr
. Hence:
x=$(expr $y '*' $z)
instead of
((x = y * z))
You don't even have to decorate the variables with $
in (( ... ))
.
(( ))
evaluates an arithmetic expression in bash
(see man bash
).[[ ]]
evaluates a logic expression in bash
(see man bash
).[ ]
is the same as test
, used to check file types and compare values (see man test
).
To answer your question:
- you want to use
/usr/bin/test
when you want totest
something but not in a shell (for examplefind ... -exec test ...
) - you want to use
(( ))
when you have an arithmetic expression to solve, AND you are using bash, because(( ))
is bash specific.
Now for some background:
The command /usr/bin/test
is required by the POSIX standard. POSIX also requires that [
is defined as an alias for test
. The only difference between test
and [
is that [
requires the final parameter to be a ]
.
Since test
is used so frequently in shell scripts, most shells have a builtin version of test
(and [
). The advantage of a builtin is that it avoids context switches. Which, depending how you use test
in your script, can be a measurable performance advantage.
I think it is safe to assume that under most circumstances it doesn't matter whether you use the system test
or the shell's builtin test
. But if you want to use test
in a find -exec
situation then of course you have to use the system test
because find
cannot use the shell test
.
(( ))
and [[ ]]
were introduced by bash (and perhaps some other shells) as syntactic sugar. (( ))
evaluates arithmetic expressions, while [[ ]]
evaluates logical expressions. Both allow you to write the expressions in a "more natural syntax".
The decision to use [[
or [
depends on whether you want to use the "more natural syntax", and, since sh does not support [[
, whether you want to depend on bash.
The decision to use (( ))
depends on whether you need arithmetic expressions, and again, since sh does not support (( ))
, whether you want to depend on bash. The POSIX alternative to (( ))
is $(( ))
. Note that there are some subtle differences in the behaviour.
The following links explain these topics in great detail:
- http://mywiki.wooledge.org/BashFAQ/031 (difference between
test
,[
and[[
) - http://mywiki.wooledge.org/ArithmeticExpression (
let
,(( ))
and$(( ))
) - http://www.ibm.com/developerworks/library/l-bash-test/index.html (all of the above)
See also:
- POSIX definition of
test
- POSIX definition of
$(( ))
Bonus: Some debian developers once argued whether they should use the system test
or the shell builtin test
, because of some differences in the implementation of the builtin test
. If you are interested in details of the differences of the system test
and the shell builtin test
then you can read the debian developer discussion here: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=267142.