[comp.sources.d] Perl: Hacking The !# Simulation

mer6g@uvaarpa.virginia.edu (Marc E. Rouleau) (04/28/88)

While the simulation of the #! hack is a very clever, useful idea (thanks,
Chip!) for those of us who suffer with the more primitive dialects of UNIX
:-), I'd like to suggest an improvement.  As you may recall, the final notion
was to place the following lines in every perl script immediately below the
#!/bin/perl line:

eval "exec /bin/perl $0 $*"
	if $running_via_sh;

This works great as long as $0 contains an complete path to the perl script;
however, such is frequently not the case.  In particular, the above solution
fails whenever the shell uses the $PATH environment variable to find the perl
script.

With this in mind I'd like to propose that something like the following be
done instead:

eval "exec /bin/perl `/usr/local/ksh -c \"whence $0\"` $*"
	if $running_via_sh;

If ksh(1) isn't available on your system, I think csh(1) has a built-in
called "which" which functions like ksh's "whence".

The only folks still left in the cold are those who have only the Bourne
shell (sh(1)).

I think the only solution for sh-only folks would be an option to perl
(perhaps -S?) which requests that it use $PATH if it exists in the evironment
or else some compiled-in default to determine the location of its script.

Comments?

	-- Marc Rouleau

syd@dsinc.UUCP (Syd Weinstein) (05/01/88)

In article <67@uvaarpa.virginia.edu> mer6g@uvaarpa.Virginia.EDU (Marc E. Rouleau) writes:
>With this in mind I'd like to propose that something like the following be
:done instead:
:
:eval "exec /bin/perl `/usr/local/ksh -c \"whence $0\"` $*"
:	if $running_via_sh;
:
:If ksh(1) isn't available on your system, I think csh(1) has a built-in
:called "which" which functions like ksh's "whence".
:
:The only folks still left in the cold are those who have only the Bourne
:shell (sh(1)).
:	-- Marc Rouleau
Even those are not left out in the cold, they can use the type internal command which finds the executable.

Now we need a way to have it automatically determine the shell type and use the appropriate command if needed.
Any authors out there that will figure out ksh, csh or sh and use whence, which, or type?


-- 
=====================================================================
Sydney S. Weinstein, CDP, CCP
Datacomp Systems, Inc.				Voice: (215) 947-9900
{allegra,bellcore,bpa,vu-vlsi}!dsinc!syd	FAX:   (215) 938-0235

mer6g@uvaarpa.virginia.edu (Marc E. Rouleau) (05/02/88)

>>eval "exec /bin/perl `/usr/local/ksh -c \"whence $0\"` $*"
>>	if $running_via_sh;
>>
>>The only folks still left in the cold are those who have only the Bourne
>>shell (sh(1)).
>
>Even those are not left out in the cold, they can use the type internal
>command which finds the executable.

But "type" prints its output in "whence -v" format, so further processing with
something like expr(1) would be necessary.

Also, not all sh's have a builtin "type": our 4.3bsd Microvax and 4.3bsd Vax
11/780 are examples.  (Now I know that 4.3bsd machines are lucky enough to have
the #! hack and therefore need not be considered in an all-inclusive solution
to this problem--I'm just wondering if _all_ sh's on machines which do _not_
have the #! hack do indeed have the "type" builtin ...)

>Now we need a way to have it automatically determine the shell type and use
>the appropriate command if needed.

I think this is all becoming much too complicated.  The original idea is
relatively elegant and simple, and, in the absence of #! for System V, it
seems like the next best thing; _however_, I really think the path-searching
complexity oughta be implemented within perl.

What if we could do something like this:

eval "exec /bin/perl -S $0 $*"
	if $running_via_sh;

The -S switch would cause the script file to be searched for either using an
algorithm implemented within perl (best case) or else by running a program
(ksh, csh, sh) the path to which is configurable and compiled in (acceptable
case).

	-- Marc Rouleau

lwall@devvax.JPL.NASA.GOV (Larry Wall) (05/04/88)

In article <75@uvaarpa.virginia.edu> mer6g@uvaarpa.Virginia.EDU (Marc E. Rouleau) writes:
: >>eval "exec /bin/perl `/usr/local/ksh -c \"whence $0\"` $*"
: >>	if $running_via_sh;
: >>
: >>The only folks still left in the cold are those who have only the Bourne
: >>shell (sh(1)).
: >
: >Even those are not left out in the cold, they can use the type internal
: >command which finds the executable.
: 
: But "type" prints its output in "whence -v" format, so further processing with
: something like expr(1) would be necessary.

I know, let's have a contest to see how many processes we can use up before
actually executing the script...

: >Now we need a way to have it automatically determine the shell type and use
: >the appropriate command if needed.
: 
: I think this is all becoming much too complicated.  The original idea is
: relatively elegant and simple, and, in the absence of #! for System V, it
: seems like the next best thing; _however_, I really think the path-searching
: complexity oughta be implemented within perl.
: 
: What if we could do something like this:
: 
: eval "exec /bin/perl -S $0 $*"
: 	if $running_via_sh;
: 
: The -S switch would cause the script file to be searched for either using an
: algorithm implemented within perl (best case) or else by running a program
: (ksh, csh, sh) the path to which is configurable and compiled in (acceptable
: case).

Let's go with the best case.

I've hacked -S into version 2.0, so you guys can stop squabbling now.  The -S
switch will cause a path search if the filename doesn't begin with '/'.

Takes about 20 lines of code to do it right.  Hacking #! into the kernel
wouldn't have been that much harder...    :-)

Larry

tif@cpe.UUCP (05/04/88)

Written 10:01 am  May  2, 1988 by uvaarpa.UUCP!mer6g in cpe:comp.sources.d
>What if we could do something like this:
>
>eval "exec /bin/perl -S $0 $*"
>	if $running_via_sh;
>
>The -S switch would cause the script file to be searched for either using an
>algorithm implemented within perl (best case) or else by running a program
>(ksh, csh, sh) the path to which is configurable and compiled in (acceptable
>case).

Along this line, it sounds like perl should have a special variable
that is like $0 only contains a full path.  I guess that still leaves
the implementation technique in question.

			Paul Chamberlain
			Computer Product Engineering, Tandy Corp.
			ihnp4!sys1!cpe!tif

lwall@devvax.JPL.NASA.GOV (Larry Wall) (05/10/88)

In article <6800012@cpe> tif@cpe.UUCP writes:
: 
: Written 10:01 am  May  2, 1988 by uvaarpa.UUCP!mer6g in cpe:comp.sources.d
: >What if we could do something like this:
: >
: >eval "exec /bin/perl -S $0 $*"
: >	if $running_via_sh;
: >
: >The -S switch would cause the script file to be searched for either using an
: >algorithm implemented within perl (best case) or else by running a program
: >(ksh, csh, sh) the path to which is configurable and compiled in (acceptable
: >case).
: 
: Along this line, it sounds like perl should have a special variable
: that is like $0 only contains a full path.  I guess that still leaves
: the implementation technique in question.

The current implementation of -S leaves the fully qualified name in $0.
In other words, if you use -S, $0 is guaranteed to point to a real filename
(though it may be relative to the current directory).

Larry Wall
lwall@jpl-devvax.jpl.nasa.gov