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?
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
| [reply] [d/l] [select] |
|
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.
| [reply] |
|
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. | [reply] |
|
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
| [reply] [d/l] |
|
|
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
| [reply] [d/l] |
|
|
|
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.
| [reply] |
|
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
| [reply] [d/l] |
|
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."
| [reply] |
|
| [reply] |
|
Re: shebang line
by Juerd (Abbot) on Jan 04, 2002 at 02:37 UTC
|
| [reply] [d/l] |
|
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,
| [reply] [d/l] |
|
|