Back: Size Limitations
Forward: Colon
 
FastBack: Colon
Up: Sh Implementation
FastForward: Environment
Top: Autoconf, Automake, and Libtool
Contents: Table of Contents
Index: Index
About: About this document

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:

 
#! /usr/local/bin/perl

Now, the script can be executed from the `tmp' directory, with the following sequence of commands:

 
$ cd /tmp
$ ./foo.pl

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:

 
#! /usr/bin/env perl

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:

 
#! /usr/bin/env guile -s


This document was generated by Gary V. Vaughan on February, 8 2006 using texi2html