History:
(see below)
Synopsis:
How to lighten the requirement for hard coding a path in an
executable script's magic first line.
Background:
Under many Unix-like systems, including Linux, a file marked as
executable can tell the kernel the name and location of the
interpreter under which it expects to be run. (The execve(2) man
is helpful.)
This is accomplished by a convention: coding special comment
text into the first line of the executable file. E.g., the
magic first line
#!/bin/bash
denotes a script which expects to be run under the "bash" shell.
This is a common case on Linux systems.
Similar magic lines are used to associate other species of script
with their respective interpreters - among them shells other than
bash, and languages such as Perl, Python, and TCL.
Problem:
This method of binding a script to its interpreter requires hard
coding: both the name of the desired interpreter and its location
in the current machine's file system must be explicitly stated.
(The PATH environment variable is not consulted in this context.)
In the example above, the interpreter must be named bash, and bash
must be in the /bin directory.
Such hard coding is usually no problem on a single system whose
directory organization is known and unlikely to change. But it
creates portability difficulties between systems. Names can vary.
File system organizations do vary.
It also makes it inconvenient to run a script under alternate
versions of an interpreter, as one might wish to do for trying
out a new release or for debugging.
A SOLUTION:
In _Learning Python_, O'Reilly & Associates, 1999, Lutz and
Ascher offer this suggestion for bringing the PATH environment
variable into play. From page 15:
On some systems, you can avoid hardcoding the path to
the Python interpreter by writing the special first-
line comment like this:
#!/usr/bin/env python
When coded this way, the "env" program locates the
"python" interpreter according to your system search
path settings (i.e., in most Unix shells, by looking
in all directories listed in the PATH environment
variable). This "env"-based scheme can be more
portable, since you don't need to hardcode a Python
install path in the first line of all your scripts;
provided you have access to "env" everywhere, your
scripts will run no matter where "python" lives on
your system.
Comments:
o Although Lutz and Ascher are writing about Python, this
technique is general. It applies to any interpreter.
o It is enlightening to read the env(1) man page to see
how this technique works.
o This technique incurs the overhead of an additional
process (probably a small price, especially for
portability).
o Bill Freeman observes that now it is the path for "env"
which must be hard coded. True. You must "have access
to 'env' everywhere".
History (if you care): A few weeks ago Bruce Dawson and I had
been discussing ways to make TCL scripts point to different
versions of the TCL interpreter. We had tried tricks with
PATH, etc., to no avail. We had tried using links, but that
was _not_ making things more portable. Then by accident one
day I happened upon this tip in Lutz and Ascher. It solved
our TCL problem.
Last week at the monadlug meeting Ray C�t� gave us an
(excellent) presentation about Perl. In the discussion
afterwards the subject of magic script lines came up. I
remembered that Bruce and I had used "env" to make them
indirect, and that the trick was described somewhere in
an O'Reilly book. I promised to look up the reference
and send it to Ray and the others. I did that (*) a few
days ago.
This "env" tip has been handy enough that it seems worth
writing it up. Perhaps someone else on this list will find
it useful.
(*) I did not know exactly where I had seen the reference. It
pretty much had to be in one of a few books - Bash, or Running
Linux, or Perl, or Python. I knew it was printed in a sidebar,
about the middle of a right-hand page. I tried one book at a
time, flipping and scanning pages. The search took only a
couple of minutes.
Printed books aren't going to become obsolete any time soon...
-Bill (treeware curmudgeon :)
**********************************************************
To unsubscribe from this list, send mail to
[EMAIL PROTECTED] with the following text in the
*body* (*not* the subject line) of the letter:
unsubscribe gnhlug
**********************************************************