22.2.2 #!
When the kernel executes a program from the file system, it checks the
first few bytes of the file, and compares them with its internal list of
known magic numbers, which encode how the file can be executed.
This is a similar, but distinct, system to the `/etc/magic' magic
number list used by user space programs.
Having determined that the file is a script by examining its magic
number, the kernel finds the path of the interpreter by removing the
`#!' and any intervening space from the first line of the script.
One optional argument is allowed (additional arguments are not ignored,
they constitute a syntax error), and the resulting command line is
executed. There is a 32 character limit to the significant part of the
`#!' line, so you must ensure that the full path to the interpreter
plus any switches you need to pass to it do not exceed this limit.
Also, the interpreter must be a real binary program, it cannot be a
`#!' file itself.
It used to be thought, that the semantics between different kernels'
idea of the magic number for the start of an interpreted script varied
slightly between implementations. In actual fact, all look for
`#!' in the first two bytes -- in spite of commonly held beliefs,
there is no evidence that there are others which require `#! /'.
A portable script must give an absolute path to the interpreter, which
causes problems when, say, some machines have a better version of Bourne
shell in an unusual directory -- say `/usr/sysv/bin/sh'. See
() for a way to re-execute the script with a better
interpreter.
For example, imagine a script file called `/tmp/foo.pl' with the
following first line:
Now, the script can be executed from the `tmp' directory, with the
following sequence of commands:
When executing these commands, the kernel will actually execute the
following from the `/tmp' directory directory:
|
/usr/local/bin/perl ./foo.pl
|
This can pose problems of its own though. A script such as the one
described above will not work on a machine where the perl interpreter is
installed as `/usr/bin/perl'. There is a way to circumvent this
problem, by using the env program to find the interpreter by
looking in the user's `PATH' environment variable. Change the
first line of the `foo.pl' to read as follows:
This idiom does rely on the env command being installed as
`/usr/bin/env', and that, in this example, perl can be
found in the user's `PATH'. But that is indeed the case on the
great majority of machines. In contrast, perl is installed in
`usr/local/bin' as often as `/usr/bin', so using env
like this is a net win overall. You can also use this method to get
around the 32 character limit if the path to the interpreter is too
long.
Unfortunately, you lose the ability to pass an option flag to the
interpreter if you choose to use env . For example, you can't
do the following, since it requires two arguments:
|