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:
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
This idiom does rely on the
Unfortunately, you lose the ability to pass an option flag to the
interpreter if you choose to use