2

I came across this construct to test whether the shell variable $foo, which could contain any arbitrary string, matched foo:

[ "x$foo" = "xfoo" ]

The purpose of prefixing with x was never explained. This looks like an attempt to avoid errors that might arise when $foo contains strings special to test like =, -f, (, or !. The GNU info manual indicates compound expressions involving -a and -o can lead to ambiguity, so I am primarily interested in simple (i.e., not compound) statements. I had a hard time searching for more information on this. I have not been able to devise an example of an arbitrary string that caused GNU test to fail in an unexpected manner, although I freely admit I'm not that clever.

My questions:

  1. What reasons are there to prefix parameter substitutions in test?
  2. Is there an example of a simple (i.e., not compound) statement involving naive parameter substitution (i.e., no prefix protection) that causes test to give unusual results?

I mostly use GNU tools on linux, but for the sake of portability, I am interested in whether test on other platforms as well.

ov2k
  • 134
  • 1

1 Answers1

1
> [ -f = -a -a -a ]
bash: [: argument expected

> [ -f = -a -a x ]

But:

[ x-f = x-a -a -a ]

doesn't work either although

[ -a ]

is fine.

Hauke Laging
  • 90,279
  • 1
    As noted, compound expressions can cause ambiguity. Can you think of a simple (i.e., not compound) expression that causes unexpected results? – ov2k Sep 19 '17 at 20:27
  • Actually, [ -a ] is a good example of an ambiguous statement. GNU test returns 0 because this is interpreted as [ -n "-a" ] rather than [ -n "" -a -n "" ]. However, prefixing does not solve anything, as [ "x$foo" ] and [ -n "x$foo" ] are always true, which defeats the purpose of the test. – ov2k Sep 19 '17 at 20:42
  • @ov2k, I can't understand your comment at all. [ -a ] is not ambiguous in any way whatsoever. – Wildcard Sep 19 '17 at 21:40
  • @Wildcard Many users would likely not recognize that [ -a ] is interpreted by test as equivalent to [ -n "-a" ], which returns 0, and not [ -n "" -a -n "" ], which returns 1. The information necessary to understand why is not present in the man page for GNU test, although it is present in the POSIX standard and the GNU info page. As it relates to my original questions, it is true that [ "$foo" ] is handled properly, and it remains unclear why a construct of the form "x$foo" might be necessary. – ov2k Sep 19 '17 at 23:03
  • @ov2k, reread the question. I think the real answer is, providing that test has three arguments or less (or [ has four or less including ]), there is no possible ambiguity. Good point. But [ -a ] still isn't ambiguous, even if some users don't know shell syntax well enough to understand it. ;) – Wildcard Sep 19 '17 at 23:45