On Sun, Dec 17, 2000 at 01:31:19PM -0600, David Talkington <[EMAIL PROTECTED]> 
wrote:
| Cameron Simpson wrote:
| >One thing I have done in my own shell setup is alias (well, shell
| >function, but the idea's the same) rm, cp, chmod, chown, chgrp and a
| >couple of others to an equivalent of
| >     ( set -x; rm ${1+"$@"}; )
| >i.e. I get to see the results of my shell expansion [...]
| 
| Ok, y'got me ... what is the thingy in the brackets doing?  set -x
| shows me the expansion, but I don't understand what the rest of it is
| doing.  In a test script, that structure returned the same output as
| $@ by itself (just the positional parameters).  Enlighten me?

That is the One True Gimme-The-Args Incantation.

Some background:

As you know, $* is the command line args stuck together with spaces (hmm,
with the first char of $IFS in some shells, which is normally a space).
It acts exactly like every other shell var in that "$*" is a single
string.

When you're passing your arguments to another command (as we are above)
you naturally don't want them stuck together as a single argument, but $*
on its own is subject to space interpretation, so calling our wrapper with:

        "this and that" "foo"

and saying

        $*

would make four strings, not two.

So...

Enter $@. Outside quotes, $@ acts like $* and any other var: space
interpretation happens. BUT... The special incantation

        "$@"

keeps the original quoting intact. Now, for reasons I have a few theories
about, there's a catch with this. If there are _no_ arguments then "$@"
doesn't result in no arguments, it results in exactly one empty argument.

So...

What you do in a robust portable script is to only use "$@" when you know
there's at least one argument. Now, the slickest way to do that is with the
handy ${+} incantation. From the manual (under "Parameter Substitution")
you'll know that the incantation:

        ${var+foo}

says ``if var is set, substitute foo, otherwise nothing''. So we say
``if $1 is set (which means $# > 0: there's at least one argument)
substitute "$@", otherwise nothing'', which neatly steps around this
corner case for "$@".

So you will find

        ${1+"$@"}

in portable wrapper scripts.

Aside: ${1:+"$@"} is wrong wrong wrong. As an exercise, tell me what it would
        break.

Thus endeth the lesson for today. Make sense? Cheers,
--
Cameron Simpson, DoD#743        [EMAIL PROTECTED]    http://www.zip.com.au/~cs/

It's a vague science.   - Rory Tate, circle researcher.



_______________________________________________
Redhat-list mailing list
[EMAIL PROTECTED]
https://listman.redhat.com/mailman/listinfo/redhat-list

Reply via email to