The difference between no argument and an empty argument
Here is a little Bourne shell quiz. Supposing that $VAR is not
defined, are the following two lines equivalent?
./acnt $VAR ./acnt "$VAR"
The answer is no. If the acnt script is basically 'echo "$#"',
then the first one will print 0 and the second one will print 1; in
other word, the first line called acnt with no argument and the
second one called acnt with one argument (that happens to be an empty
string).
Unix shells almost universally draw some sort of a distinction between
a variable expansion that results in no argument and an empty argument
(although they can vary in how you force an empty argument). This is
what we're seeing here; in the Bourne shell, using a "..." forces
there to always be a single argument regardless of what $VAR expands
to or doesn't.
Sometimes this is useful behavior, for example when it means that a
program is invoked with exactly a specific number of arguments (and with
certain things in certain argument positions) even if some things aren't
there. Sometimes this is inconvenient, if what you really wanted was to
quote $VAR but not necessarily pass acnt an empty argument if $VAR
wound up unset. If you want this latter behavior, you need to use the
more awkward form:
./acnt ${VAR:+"$VAR"}
(Support for this is required by the Single Unix Specification and is present in Solaris 10, so I think you're very likely to find it everywhere.)
Note that it can be possible to indirectly notice the presence of empty arguments in situations where they don't show directly. For example:
$ echo a "$VAR" b a b
If you look carefully there is an extra space printed between a and b
here; that is because echo is actually printing 'a', separator space,
an empty string, another separator space, and then 'b'. Of course some
programs are more obvious, even if the error message is a bit more
mysterious:
$ cat "$VAR" cat: : No such file or directory
(This entry is brought to you in the process of me discovering something
interesting about modern versions of test, but that's another entry.)
|
|