[net.unix] Fun

idallen@watmath.UUCP (03/24/84)

What does this line in a Bourne Shell command file print, when called
with the command arguments "1 2 3 4"?

   sh -c "/bin/echo And $@ were my arguments."

Answer:

   And 1

Why?  Because of the way "$@" expands, the command line becomes:

   sh -c "/bin/echo And 1" "2" "3" "4 were my arguments."

The invoked shell silently ignores the "2" and all following arguments,
and it executes "/bin/echo And 1".  I suppose this variation on the
expansion of "$@" makes sense (?!), but what reason is there to silently
ignore the following arguments?  (p.s. To fix the problem, change @ to *.)
-- 
        -IAN!  (Ian! D. Allen)      University of Waterloo

rpw3@fortune.UUCP (03/25/84)

#R:watmath:-735600:fortune:26900034:000:1844
fortune!rpw3    Mar 24 20:22:00 1984

+--------------------
|    sh -c "/bin/echo And 1" "2" "3" "4 were my arguments."
| 
| The invoked shell silently ignores the "2" and all following arguments,
| and it executes "/bin/echo And 1".  I suppose this variation on the
| expansion of "$@" makes sense (?!), but what reason is there to silently
| ignore the following arguments?  (p.s. To fix the problem, change @ to *.)
|         -IAN!  (Ian! D. Allen)      University of Waterloo
+--------------------

Sorry, Ian, it isn't "broken". Your "problem" comes from a mis-interpretation
of two subtleties: (1) The normal default behaviour of extra arguments,
and (2) the meaning of "$@".

1. Any program is allowed to ignore extra arguments, even if some few programs
   go to great lengths to validate the entire argument string (e.g., "mv").
   In this case, "sh -c" is DEFINED to have exactly ONE additional argument
   to the "-c", which is the command (singular) to be executed.  See the man
   page, which is quite clear about that. It may not be all that polite in
   your opinion to ignore extra args, but "sh -c cmd" is not usually used
   by people, but by programs that don't appreciate the extra chatter.
   (For better or worse, "the UNIX way".)

2. The "$@" construct is doing EXACTLY what it is documented to do. It is NOT
   a "variation on the expansion", it the ONLY defined meaning. If you want
   all the positional args collected into ONE "word", use "$*", yes. If you
   want one "word" for each positional arg, use "$@". It makes a big difference
   deep down in one's shell scripts which you use. You just used the "wrong"
   one (that is, if you wanted the other answer).

[End of not-a-flame]

Rob Warnock

UUCP:	{sri-unix,amd70,hpda,harpo,ihnp4,allegra}!fortune!rpw3
DDD:	(415)595-8444
USPS:	Fortune Systems Corp, 101 Twin Dolphin Drive, Redwood City, CA 94065