Reputation: 1329
From $ help test
:
test: test [expr]
Evaluate conditional expression.
Exits with a status of 0 (true) or 1 (false) depending on the evaluation of EXPR. Expressions may be unary or binary. Unary expressions are often used to examine the status of a file. There are string operators and numeric comparison operators as well.
I'm a bit confused as to what expr
can supposedly contain. The help page for test
indicates that it is a conditional expression, consisting of file, string or numeric operators. So how does the string comparison operator cause unwanted file re-direction?
$ [ "a" > "b" ]
$ ls -la
-rw-rw-r-- 1 user user 0 May 28 17:22 b
I understand that to prevent re-direction I need to escape >
, but I'm confused why. It's not like I can place any command as the expr
:
$ [ echo "hello" ]
bash: [: echo: unary operator expected
As far as I can make out from the help text test
only evaluates pre-defined operators in expr
- file re-direction not being one of them. test
/[
are only meant to evaluate conditional expressions - I'm limited to only the operators that test
accepts, and arguments it accepts with them.
(For comparison, with the following built-in there is no confusion as to what >
means and no escaping is necessary):
$ echo $[2>1]
1
So what is interpreting >
as re-direction meaning escaping is needed?
Upvotes: 1
Views: 85
Reputation: 531165
test
is an ordinary command, not special syntax, and as such undergoes the same processing as any other command.
[ "a" > "b" ]
is just a (overly) clever synonym for
test "a" > "b"
and so >
is interpreted as an output redirection before the arguments to test
are identified. The exact same command can be written
[ "a" ] > "b"
To prevent the shell from recognizing >
as the redirection operator, it must be escaped.
[ "a" \> "b" ] # or [ "a" ">" "b" ]
The other example you gave, $[2>1]
is special syntax (not simply a built-in command), and so doesn't undergo the same processing. $[...]
is an obsolete, no-longer-documented, form of arithmetic expansion, equivalent to $((2>1))
. As special syntax, the shell parses the contents of $[...]
different than it would an ordinary command.
A note on ]
. test
is a regular command, and so is responsible for interpreting its arguments as it sees fit. The following are all syntactically correct:
test a \> b
test a \> b ]
[ a \> b
[ a \> b ]
However, only 1 and 4 are semantically correct. When used as [
, the final argument must be ]
to maintain the illusion of [ ... ]
as merely "grouping" the expression.
$ [ a \> b
bash: [: missing `]'
When used as test
, ]
is not a valid part of an expression at all, and must be omitted.
$ test a \> b ]
bash: test: too many arguments
Upvotes: 4