I noticed while answering another question that test
and [
are different binaries, but the [
manpage pulls up test
's. Besides the requirement for an ending ]
, is there any difference? If not, why are they separate binaries instead of being symlinked? (They are also bash
builtins, and bash
doesn't show a difference either.)
2 Answers
The source code explains the difference as being how it handles the --help
option.
/* Recognize --help or --version, but only when invoked in the "[" form, when the last argument is not "]". Use direct parsing, rather than parse_long_options, to avoid accepting abbreviations. POSIX allows "[ --help" and "[ --version" to have the usual GNU behavior, but it requires "test --help" and "test --version" to exit silently with status 0. */
Demonstrating
$ /usr/bin/test --help
$
$ /usr/bin/[ --help
Usage: test EXPRESSION
or: test
or: [ EXPRESSION ]
or: [ ]
or: [ OPTION
Exit with the status determined by EXPRESSION.
[...]
In the bash
builtin version, the only difference is that [
requires ]
at the end, as you said.
-
1Interesting, though most programs achieve the same behavior with a symlink.– KevinCommented May 6, 2012 at 16:33
-
2They're hardlinks to the same inode on my system. The benefit of this over symlinks is that if the symlink target gets removed or moved, the symlink no longer works. If one of the hardlinks to an inode gets moved or removed, all the hardlinks continue to work.– nobodyCommented Jun 20, 2014 at 15:56
Normally, they are the same binary with hard links. Depending on the shell, an internal implementation may be used for test
and [
tests rather than the binary. This is more efficient in terms of process spawning, and may provide different options than the binary program test
provides.
Other than the the differences in call format, they both provide the same functionality.
-
8Amazingly enough, in Debian's coreutils they aren't the same binary. The same source is compiled two times, one defining PROGRAM_NAME as "test", and other defining it as "[" and with some additional code to test that the expression ends with "]". o_O– angusCommented Jan 9, 2012 at 17:58
-
3@angus Another example of this is ls/dir/vdir. Coreutils seems to like building different hardcoded binaries rather than testing argv[0] at runtime. Commented Jan 9, 2012 at 18:22