in reply to Re: shebang line
in thread shebang line

Thanks very much. That's the answer I was looking for. Where did you find all the information on how the #! works anyhow? I'd like to read up on it more. Also, I believe that perl ignores the -w switch (referring to your question above..). I ran some tests by requiring an executible perl script from within another perl script. The required perl script has the -w switch on the shebang line. When I run the main script, everything is ok. Nothing is printed to stderr or stdout. However, if I modify the script that is being imported by removing the -w switch, and instead insert the "use warnings" pragma, then a warning is printed to stderr. This leads me to believe that the shebang line in the imported file is ignored.

Replies are listed 'Best First'.
OT: shebang line docs
by mr_mischief (Monsignor) on Jan 04, 2002 at 07:09 UTC
    On Linux:

    $ man execve

    From the DESCRIPTION section, first paragraph (RedHat 6.2 anyway):
       execve() executes the  program  pointed  to  by
       filename. filename must be either a binary
       executable, or a script starting with a line of
       the form "#!  interpreter  {arg}". In  the latter
       case, the interpreter must be a valid path­ name
       for an executable which is not itself a script,
       which will be invoked as
       interpreter {arg} filename.
    

    So yeah, if you know where to look or dig around enough, it's there to be found without buying a book. Such is often the case with Perl/perl, Linux, BSD, Postfix, Apache, and many other projects in the OS/FS world.
Re(3) shebang line
by dmmiller2k (Chaplain) on Jan 04, 2002 at 03:09 UTC

    Not sure, exactly where I picked this stuff up; somewhere along the way, I suppose. You could probably use a decent UNIX and/or shell (sh/csh/ksh/bash/etc.) handbook. Check the library or bookstores, I suppose (can't remember any specific titles to recommend).

    dmm

    You can give a man a fish and feed him for a day ...
    Or, you can
    teach him to fish and feed him for a lifetime
      Mostly correct, but with some caveats.

      First, when asked to execute a file, the kernel reads in the first 32 characters, minimum, not just the first two. Some of the older OS's only read the first 32 characters (POSIX spec, perhaps?), but I believe linux reads in 256. Then it checks if the first two characters if that line are #!, and if so, executes the program given by the path following the #!, up until the max characters that it read. Also, I believe it only looks at the first set of switches ('#!/usr/bin/perl -ixv' would get passed, but '#!/usr/bin/perl -i -x -v' would get passed as '#!/usr/bin/perl -i').

      There's a little bit more to it, but those are the basics.

      update: Disregard this. If I would have just looked around a bit, I would have noticed that everybody else basically said the same thing...

Re: Re: Re: shebang line
by helgi (Hermit) on Jan 04, 2002 at 16:36 UTC
    This leads me to believe that the shebang line in the imported file is ignored.

    No, it isn't. You probably have a carriage return leftover from a PC somewhere between #!/perl and -w (invisible on Unix, but seen in some text editors as a ^M.

    Get rid of it by transferring the file with ASCII mode FTP to the Unix box or with this regex:

    s/\r\n*/\n/g;

    Regards, Helgi Briem

      Read carefully: "This leads me to believe that the shebang line in the imported file is ignored."

      By imported, perlmongrel is referring to used or required files, NOT the main .pl file. Since in these cases Perl simply opens and reads the files, the shell and the kernel are out of the picture (at least from the execve perspective); this happens well after any shebang interpretation. So in that sense, he is right.

      I believe, however, that Perl itself may, upon detecting a shebang line in an included file, honor at least the -w and -T switches, if present. The former in the usual sense, and the latter only insofar as it has to match the Taint-mode-ness of the main .pl file. However, I cannot remember where I read this and am not particularly certain of either of these points. Certainly, Perl WILL ignore the path to the perl interpreter if it differs from that of the running instance.

      As to having an "invisible" CR (^M) *between* #!/path/to/perl and -w, balderdash! No Win/DOS editor would put anything but CR-LF into a text file, and those only go at the ends of lines. So if anything, adding a -w would move an extraneous CR (inserted by a Win/DOS editor) from right after #!/path/to/perl to just after the -w, in which location, as I explained in an earlier post, it is ignored by Perl.

      Using ASCII mode to FTP the files, or using one of several CR-stripping mechanisms (of which your regex is one) would emeliorate the problem.

      dmm

        dmm writes: "I believe, however, that Perl itself may, upon detecting a shebang line in an included file, honor at least the -w and -T switches, if present."

        After running some tests, I found that this is true when perl is run from the command line, such as this:

        % perl file.pl

        In this case, the interpreter does enable the -w and -T switches if they are present on the shebang line in the file passed to perl. However, this does not appear to be the case for imported files.

        Here's what I did:

        First, I created a file like this:

        #!/usr/bin/perl

        require "o.pl";

        exit 0;
        Next, I create the o.pl file:

        #!/usr/bin/perl -w

        print "y $s\n";

        1;

        When running the first file, no warning is printed. However, if you enable the -w switch on the shebang line of the first file, then the following warning will be returned:

        Use of uninitialized value in concatenation (.) or string at o.pl line 3.
        y

        Further, if you remove the -w switch from the shebang line in o.pl and from the main script, and instead use the warnings pragma in o.pl, the warning will be returned.

        Like this:
        #!/usr/bin/perl

        use warnings;

        print "y $s\n";

        1;

        I used perl 5.6.1 for testing.

        Thanks again!

        -perlmongrel

        Imagination is the one weapon in the war against reality. -- Jules de Gaultier