in reply to shebang line

Not stupid, just not necessarily Perl. The shebang line is a UNIX-ism.

On UNIX-en (includes Linuxen as well) when you attempt to execute any file (any file, that is, which is has its executable bit set), the shell "peeks" at the first two characters lokoing for the shebang combination, "#!". If it finds them, it reads the remainder of the line up through, but not including, the terminating newline.

It breaks apart whatever it finds into tokens, split by whitespace, and calls exec() with the first token as the command, and the remaining tokens passed as arguments (in much the same way it does with manually typed commands at the prompt), and with the current filename (i.e., '/path/whatever.pl') appended to the list of arguments.

The exec() call normally causes the current process image (i.e., the shell) to be replaced with that of the command line (say, Perl). And away we go executing whatever script you've run with the appropiate interpreter.

OK, enough background. That explains what happens when you type 'whatever.pl' at the shell prompt.

Now, for your question: If the shebang line invokes Perl on the file, it will examine the shebang line itself to pick up any options that may not have made it through the command lne passed by the original shell (some UNIX-en have an arbitrarily short limit on the number of characters they can accept on the shebang line -- occasionally as few as 32), and will then start reading/compiling the perl code, including processing requires and/or uses, as necessary.

Any shebang lines in THOSE files will not be looked at, AFAIK, (although perl may actually honor any '-w' switches in them--I forget, exactly).

Update: Apparently, Perl will try to honor any -T switches (as insofar as they have to match the taint-mode-ness of the main .pl file).

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

Replies are listed 'Best First'.
Re: Re: shebang line
by perlmongrel (Acolyte) on Jan 04, 2002 at 03:00 UTC
    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.
      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.

      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...

      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

not the shell
by Anonymous Monk on Jan 04, 2002 at 04:10 UTC
    In all of the UNIX-style OSes I know of, shebang interpretation is left to the kernel, not to the shell. the #! is basically just another magic number for a particular executable type. The kernel execs the interpreter specified, passing the fully qualified name of the script as the last parameter.

      I believe you are right -- when attempting to execute a file, the kernel (in the form of the exec family of system calls), opens the file, reads some number of bytes (32 or 256, or whatever), and upon detecting a shebang, copies the command line embodied there, closes the file and builds a new command line using the shebang as the command, with the name of the original file appended and followed by any command-line arguments. The process may repeat as needed until finally some binary is executed, using a command line commensurate with all the preceding steps.

      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
Re: Re: shebang line
by frag (Hermit) on Jan 04, 2002 at 04:41 UTC
    It ain't just 'nixen. The bash that comes with cygwin seems to do the right thing, too.

    -- Frag.
    --
    "Just remember what ol' Jack Burton does when the earth quakes, the poison arrows fall from the sky, and the pillars of Heaven shake. Yeah, Jack Burton just looks that big old storm right in the eye and says, "Give me your best shot. I can take it."

      Yes, but isn't bash (and in fact, Cygwin itself) a UNIX-ism?

      dmm

        True. I just wanted to point out that this behavior isn't limited to *nix OSes.

        -- Frag.
        --
        "Just remember what ol' Jack Burton does when the earth quakes, the poison arrows fall from the sky, and the pillars of Heaven shake. Yeah, Jack Burton just looks that big old storm right in the eye and says, "Give me your best shot. I can take it."