[
command returns exit-status zero if expression, contained in its arguments, is considered true and non-zero exit-status if expression, contained in its arguments, is considered false. It also fails with error message if its last argument isn't ]
(this is done purely for aesthetic reasons).
E.g.:
[ hello ]
echo "Exit-status of [ hello ] is:" $?
[ abc = abc ]
echo "Exit-status of [ abc = abc ] is:" $?
[ ]
echo "Exit-status of [ ] is:" $?
[ abc = def ]
echo "Exit-status of [ abc = def ] is:" $?
… will output:
Exit-status of [ hello ] is: 0 — because non-empty string is considered true
Exit-status of [ abc = abc ] is: 0 — because 'abc' really is same as 'abc'
Exit-status of [ ] is: 1 — because empty string is considered false
Exit-status of [ abc = def ] is: 1 — because 'abc' really differs from 'def'
However, bash and many other shells really usually don't invoke /bin/[
(or /usr/bin/[
) in these cases, but call built-in command with exactly the same behavior instead (purely for performance reasons). To invoke /bin/[
(not shell built-in surrogate) you need either to explicitly specify its path (e.g. /bin/[ hello ]
; you don't need to prefix ]
with dirname though ☺), or to configure shell not to use a built-in surrogate (for example, enable -n [
in bash).
P. S.: As it was said in other answers, [
is related to test
. But test
, unlike [
, doesn't require ]
as its last argument (and doesn't expect it at all; adding extra ]
to test
arguments can cause it to fail with error message or to return wrong result). The /bin/test
and /bin/[
can resolve to the same file (e.g. one is symlinked; in this case the behavior diversion is probably implemented by analyzing the currently-called command within the test
/[
code itself) or to different files. For test
, shell also usually invokes built-in surrogate, unless path is explicitly specified (/bin/test
) or it's configured not to do so (enable -n test
).
P. P. S.: Unlike test
and [
, modern if
is never a real file. It's part of shell (e.g. bash) syntax: if commandA; then commandB; fi
(newlines can be used instead of semicolons) causes commandB
to be executed if-and-only-if commandA
exited with zero status. This perfectly fits to behavior of test
or [
, allowing to combine them like if [ "$a" = foo ]; then …; fi
(or if test "$a" = foo; then …; fi
— just less readable). However, modern scripts often use [[
instead of test
or [
, which (as the if
) is never a real file, but always a part of shell syntax.
P. P. P. S.: As for man
— never expect man
to have an article on every command in your file-system. Info on some (even "real", file-based) commands may be missing, info on some shell built-ins maybe present not only within an article dedicated to specific shell (that's the place where you most certainly will find info on test
, [
, if
, [[
). Still, many distributions have explicit man
-articles for test
and [
. (About --help
, it's not recognized with test
for obvious reason: it needs to handle quietly cases like a=--help; test "$a"
; on some distributions [ --help
(without closing ]
) still shows help, on some it doesn't.)
[
refers totest
command though, notexpr
, so it should beman test
– Sergiy Kolodyazhnyy Jan 11 '17 at 9:55man '['
works fine for me - either you forgot to quote[
or you have a different definition of "works". – Toby Speight Jan 11 '17 at 10:48[
evaluates its arguments, so you need to have spaces between all of them.[ a=b ]
is not a comparison: it will always be true (it is a single string: "a=b", which is always evaluated to true) And you should limit the number of arguments to 4 (even though recent implementations will allow more... limiting to 4 makes it more portable. For example :[ "a" = "b" ]
already has 4 arguments : "a" "=" "b" and the non-necessary end of test arg : "]" ). If you need more: chain tests with for example:if [ "$Var_a" = "foo" ] && [ "$Var_b" = "bar" ] ; then : do something ; fi
– Olivier Dulac Jan 11 '17 at 12:02!
by itself (unescaped and unquoted) won't be replaced, and even better would beif ! [ ...
. All of the bash expansions that use!
include at least on other character – muru Jan 11 '17 at 12:23[
-builtin inbash
(and possibly other shells as well), and that this may be used instead of/bin/[
. Also there is thetest
-command, which on many systems is a symbolic link to/bin/[
(or vice versa) - but on others is a separate command. – Baard Kopperud Jan 11 '17 at 23:20