Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

shebang line

by perlmongrel (Acolyte)
on Jan 04, 2002 at 02:27 UTC ( [id://136121]=perlquestion: print w/replies, xml ) Need Help??

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

Hi. I know this sounds pretty stupid, but I just can't find a blurb anywhere in the perl book that confirms my suspicions. On UNIX/Linux platforms, if you import (require or use) a script into your program that has a shebang line in it, does it not just ignore that shebang line? I'm pretty sure it does, since you've already got an interpreter running at that point. However, what confuses me is the fact that perl can interpret a shebang line for another interpreter, such as the bash shell. Therefore, what happens when it crosses an shebang line with the perl interpreter?

Replies are listed 'Best First'.
Re: shebang line
by dmmiller2k (Chaplain) on Jan 04, 2002 at 02:49 UTC

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

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

Re: shebang line
by Juerd (Abbot) on Jan 04, 2002 at 02:37 UTC
    perl will only check for shebangs containing a -T flag. It will only check a comment on the very first line it parses, so not in modules or on the second line etcetera.
    If you have a shebang using -T, perl will die stating Too late for "-T" option at foo line 1. if you run perl yourself (perl foo.pl).

    2;0 juerd@ouranos:~$ perl -e'undef christmas' Segmentation fault 2;139 juerd@ouranos:~$

      Perl doesn't just look for -T.

      As documented in perlrun, Perl will look for its various command line flags on the #! line. It will die for -T because at the point where it is reading the command line it is too late for it to switch into taint-mode. Most others will work just fine.

      UPDATE</b
      Also Perl has a few other tricks up its sleeve. For people on very old Unix systems without a #! line, you can use perl as your shell and it will work. To see this in action try running the following with Perl:

      #! /bin/sh echo Just another Perl hacker,

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://136121]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (2)
As of 2024-04-25 06:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found