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. | [reply] |
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
| [reply] [d/l] |
|
|
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...
| [reply] |
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
| [reply] [d/l] |
|
|
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
| [reply] [d/l] [select] |
|
|
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
| [reply] |