cadphile has asked for the wisdom of the Perl Monks concerning the following question:

In a perl script, in the top lines, where one designates the interpreter, the perl wisdom for systems where the kernel might not do the right thing with a "#!" line, is to use the form:
#!/bin/sh -- # -*- perl -*-
eval 'exec /data/local/bin/perl -S $0 ${1+"$@"}'
  if $running_under_some_script;
So, why ${1+"$@"} instead of just "$@"? I know that "$@" expands to all the arguments quoted (e.g. "$1" "$2", etc). But the other form I don't quite see. I mean, what's the 1+ do? I've searched the for the documentation on what this extra bracketed format accomplishes, and I can't find it. And surprisingly, Google can't handle that search string.

If someone knows the answer, or an online reference to this, I'd be very happy...

cheers!
-cadphile...

Replies are listed 'Best First'.
Re: what's the difference between "$@" and ${1+"$@"}
by merlyn (Sage) on Oct 05, 2007 at 23:47 UTC
    There was a bug in the One True Shell (/bin/sh on V7) such that a simple "$@" would fail miserably if nothing at all was passed. So we old-timers learned to write the extended version instead. Since the code that generates that #! line was no doubt written in the Perl1 days, the legacy was carried forward, although no modern shell probably still suffers the same bug.
      such that a simple "$@" would fail miserably if nothing at all was passed

      "fail miserably" meant (on my systems back then, anyway) that "" (a single empty argument) got passed instead of no arguments. It was considered more of a design quirk than a bug in my neighborhood, since it made sense for $@ to expand to something like foo" "bar (if two arguments were passed) but didn't make as much sense for $@ to make surrounding quotes, if present, just magically disappear (if no arguments passed).

      - tye        

      The syntax isn't quite ${1:+$foo}, and hence "this" or "that". I've never seen any documentation of the syntax ${foo+"$bar"}.

      I'm just curious what the 1+ does in this context. If there are actual arguments in "$@", the 1+ doesn't seem to modify the end result at all. So, if "$@" is empty, do we get instead the return value of the first positional parameter $1, which happens also to be empty? Or does the 1+ just act to clean up the return value of the empty "$@".

        From the manual,

        If the colon (:) is omitted from the above expressions, the shell only checks whether parameter is set or not.

Re: what's the difference between "$@" and ${1+"$@"}
by liverpole (Monsignor) on Oct 05, 2007 at 23:44 UTC
    Hi cadphile,

    My /(ba)?sh/-fu is notoriously weak, so I referred to the bash manual:

    3.5.3 Shell Parameter Expansion ${parameter:+word} If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted.

    I take that to mean that if argument $1 (ie. ${1}) is null, nothing gets substituted, but if not, it's replaced by all arguments.  In other words, perhaps it's a clean way of referring to all arguments, and not failing if none are specified?  That's my best guess, anyway.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/