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.

You’ll also like:

© 2023 -