Reputation: 11226
I have seen scripts using the test
command and [ ]
or [[ ]]
. But when do we need to use /usr/bin/test
and (( ))
?
Are there any occasions when we need to go for the latter?
Regards, John
Upvotes: 19
Views: 12177
Reputation: 27073
To answer your question:
/usr/bin/test
when you want to test
something but not in a shell (for example find ... -exec test ...
)(( ))
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:
test
, [
and [[
)let
, (( ))
and $(( ))
)See also:
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.
Upvotes: 21
Reputation: 754560
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 (( ... ))
.
Upvotes: 3
Reputation: 14147
(( ))
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
).
Upvotes: 6