Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
These "gubbins" are needed only when you encounter a platform which does not handle shebang lines (#!...). Those platforms generally will pass anything to the sh interpreter what does not look like a binary executable file (== does not have the format of an a.out or ELF ...). Therefore if you're sure you or your users won't execute those programs on such platforms then you can replace them safely with the simple shebang.

Let's investigate this (the first case coming from perlrun):

#!/usr/bin/perl eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}' if $running_under_some_shell;

This code will be passed first to sh. sh will interpret the shebang line as a comment, then will look at the second line as a command terminated by the newline, so the if line is not relevant in this case.

If only sh would interpret this code, then the eval would not be needed and this would suffice:

exec /usr/bin/perl -wS $0 ${1+"$@"}

However later this line will be seen by perl also, that's why we should find a construct that is syntactically valid both in sh and in perl. The eval '...' construct fulfills this.

At this point sh is interpreting the eval line, not looking ahead what will follow in the source file, and never will encounter the if line because it is replacing itself with a perl process by using exec.

perl is called with two options (-w and -S), you already know the meaning of those. Then in the perl command line follows the name of the actual script ($0) and all the command line arguments passed to this script (${1+"$@"}).

"$@" expands to the positional parameters in sh terminology, so it is equivalent to "$1" "$2" "$3" ...

The ${parameter:+word} syntax is explained in the man page of bash (in the Parameter Expansion section):

${parameter:+word}
Use Alternate Value. If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted.
And omitting the colon from the construct above is also explained there:
... bash tests for a parameter that is unset or null; omitting the colon results in a test only for a parameter that is unset

As I see ${1+"$@"} can be simplified to "$@". The only difference is that in the first case only $1 will be checked whether it is set.

Okay, if the exec succeeded then now we have a running perl processing the same file getting the same arguments. The shebang line is a comment for perl also, but the newline is not a statement separator in perl, so the first statemant is eval '...' if $running_under_some_shell;. As this variable will be always false, this is semantically a no-op, so perl will happily skip it, and execute the rest of the file.

If you write eval '...' if 0; it has the same meaning, but you won't get the warning $running_under_some_shell used only once.

I'm not really knowledgeable in the c shell, so I can't explain now the gubbin designed for sh and csh at the same time.

I hope this helps understanding what is going on.

In reply to Re: Running Under Some Shell by rubasov
in thread Running Under Some Shell by Xiong

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others making s'mores by the fire in the courtyard of the Monastery: (8)
    As of 2014-09-21 16:48 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      How do you remember the number of days in each month?











      Results (172 votes), past polls