bash [: too many arguments greater than symbol
Answer #1 100 %Your workaround is effective, as long as the string stored in $A
is not an operator that [
/ test
recognizes - simply adding a space is sufficient, as you've discovered.
Surely the "greater than" should be interpreted as just a string? It works with '> ' after all.
No, the content of $A
is not interpreted as just a string. (If you wanted that, you'd have to use [[
instead, which is parsed in a special context, more like you'd expect from traditional programming languages.)
[
(test
) is a builtin (also exists as an external utility on most systems) and is therefore parsed with command syntax, which means:
- the shell performs its expansions first -
$A
references are replaced with the content of the variable in this case. - the result is then passed to
[
Thus, from the perspective of [
, it doesn't matter whether or not the operator it ultimately sees - >
in your example - came from a literal or was stored in a variable.
But note that whitespace matters: passing >
(no spaces) is interpreted as an operator; >
, by contrast, >
is not - because that exact literal is more than just the operator.
The bottom line is:
- The bash-completion script you're using is not robust.
- As @chepner states in a comment on the question, POSIX recommends not using
-o
/-a
to avoid the ambiguity you encountered (emphasis mine):
The XSI extensions specifying the -a and -o binary primaries and the '(' and ')' operators have been marked obsolescent. (Many expressions using them are ambiguously defined by the grammar depending on the specific expressions being evaluated.)
Specifically, using separate
[ ... ]
expressions joined with&&
(instead of-a
) and||
(instead of-o
) solves the problem:[ -n "$BASH_VERSION" ] && [ -n "$PS1" ] && [ -z "$BASH_COMPLETION_COMPAT_DIR" ]
Or, more simply, taking advantage of a non-empty string evaluating to true:
[ "$BASH_VERSION" ] && [ "$PS1" ] && [ -z "$BASH_COMPLETION_COMPAT_DIR" ]
Note that while -a
and -o
introduce ambiguities, they are not a security concern - you cannot inject arbitrary code through their use.