Subject: Changing exec's #! behavior
To: None <tech-kern@netbsd.org>
From: Jason R Thorpe <thorpej@zembu.com>
List: tech-kern
Date: 06/13/2000 11:29:59
Hi folks...
A co-worker recently ran into a problem where the construct:
#!/usr/bin/env perl -w
was working on a Solaris system, but not a NetBSD system.
#! is defined to be the following on both systems (paraphrased):
#! /path/to/interpreter [arg]
`interpreter' is invoked with the pathname to the interpreter
as argv[0]. If the optional `arg' is specified, it is passed
as argv[1] to the interpreter. The interpreter is then passed
$0, $1, ... $n of the original exec.
That is to say:
foo.pl:
#!/usr/bin/env perl
./foo.pl one two three
env(1) gets:
argv[0] = /usr/bin/env
argv[1] = perl
argv[2] = ./foo.pl
argv[3] = one
argv[4] = two
argv[5] = three
The problem is that BSD and Solaris are defining [arg] differently
in the #! specification. In BSD, [arg] is defined as "until the end
of the line" whereas in Solaris, it's defined as "until the first
whitespace".
This means that the following:
foo.pl:
#!/usr/bin/env perl -w
shows up as the following on Solaris:
argv[0] = /usr/bin/env
argv[1] = perl
argv[2] = ./foo.pl
argv[3] = one
argv[4] = two
argv[5] = three
and the following on NetBSD:
argv[0] = /usr/bin/env
argv[1] = perl -w
argv[2] = ./foo.pl
argv[3] = one
argv[4] = two
argv[5] = three
env(1) subsequently complains that it cannot exec "perl -w" because it
doesn't exist.
Now, the reason that the -w is seen by perl in the Solaris case is
because perl *itself* looks at the script for a line that has "#!" and
"perl" in it, and upon finding it, parses the command line args to
perl located there itself.
I've changed NetBSD's exec_script.c to have the Solaris behavior and
am using it that way in our environment here. But I'd like to get
comments on this before I commit the change to the master NetBSD
sources.
--
-- Jason R. Thorpe <thorpej@zembu.com>