bug-sh-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Possible bug in env Re: Is there a way to make env invoke perl


From: Bob Proulx
Subject: Re: Possible bug in env Re: Is there a way to make env invoke perl with -w ?
Date: Fri, 19 Apr 2002 23:43:51 -0600

> We have had a long discussion and I have finally come to the conclusion that 
> env cannot envoke any interpreter with an argumetn, in spite of what the man 
> and info pages say

Thank you for your report.  However, you are confusing the operating
systems actions with those of env.  What you are seeing is not a bug
in env but a limitation of the operating system.  The env command can
take many arguments.  But the #!interpreter syntax may only take one.
Everything after the interpreter is passed as a single argument.

> It works on the command line, as show below, but in a script it fails, 
> treating the argument as part of the executable's name, as if it was quoted..

> TA >Apparently, this will work from the command line:
> TA >
> TA >  env - perl -we 'print "Foo\n"'  
> TA >
> TA >but not from a shell script. Interesting. Not sure what to tell you.

Since it works from the command line you must know that the command is
working properly and that the problem must be elsewhere.

> Please, is there any way to get env to envoke perl with the -w and -T 
> options? 
> JW >#!/usr/bin/env perl -w

The #! syntax is generally called the Berkeley #! hack.  It was a
wonderful improvement over not having it at all.  But is still
considered a hack because it has many limitations.  One is that only
one argument is allowed.  Some operating systems have a limit of not
more than 32 characters for the line allowed.  Another is that it must
be a binary program and not another shell interpreter. These have
nothing to do with the 'env' command itself.  You may substitute any
command there such as my favorite which is 'echo' and you will see the
same limitation imposed by the underlying operating system.

> JW >Apparently env thinks "-w" is a binary to execute in addition to perl.

It is the same as if you had said the following and passed the two
things as one thing to env.  Env is not a shell and does not split
arguments on white space or quoting.  You would need to use a shell
for that.

  env 'perl -w'
  env: perl -w: No such file or directory

W. Richard Stevens documents this best in Advanced Programming in the
UNIX Environment.  The HP-UX man pages document this in the 'man exec'
page.  Most basic shell programming texts should document this when
talking about the #! line.  The Programming Perl "camel" book
documents this but gets the details wrong which you will find if you
experiment with it and I won't detail that here.  You did not say or I
did not see which operating system you were running on and therefore I
cannot suggest where that might be documented on your system.  The
possibilities are large and my experience is limited.

> JW >#!/usr/bin/env perl -w

What happens is that the kernel processes the first two characters of
the file looking for #!.  If those are found then it skips all space
characters looking for a non-space character and extracts the
interpreter path which must be a real executable and not another
script, although linux extends that to allow recursive script
processing.  Having found that then it skips to the first non-space
character where it takes from there to the next newline character and
passes that as a single argument to the command.  There is no 'shell'
processing of quotes or other meta characters.  It is all very simple
and brute force.  Therefore you cannot get fancy with options there.
You get exactly one argument white space included and 'perl -w' is
what the kernel sees here and passes on.

> It is a very big problem for us. I can use "use warnings" in place of -w but 
> there is no replacement for -T.

I am surprised that since perl offers $^W as a synonym for -w that
nothing exists for -T as well.  With perl4 the 'taintperl' program
would have worked here.  But that has been obsoleted from perl5.

Hmm...  You might investigate the perl -x option however I can't think
of any way to effectively use it in your particular situation.  The
perl design of option processing is problematic to the point of
unusability because perl wants to see 'perl' on the line and will
recursively process the file if it is not there and will get stuck.
But if it is there then shells will be confused by it.  This is
contrary to camel book documentation and has caused me fits in the
past.

If you must use 'env' to be able to find perl on PATH instead of from
a hard coded location (which I need to in some applications myself)
then you might need to create a custom wrapper program which does the
processing that you want.  Call it mytaintperl or whatever.  Have it
pass the -T option to perl.  Have '#!/usr/bin/env mytaintperl' pass
control through the wrapper.  If you get stuck on that let me know as
I am sure I have code that does similar enough things.  It should not
be more than a few lines of C code.

Perhaps one of the perl groups would have better suggestions.

HTH
Bob

> See below for portaions of our thread on the topic (address@hidden)
> 
> Thank you! 
> 
> 
> JW >Hey,
> JW >
> JW >I just ran into a rather serious (for me) problem where some users were 
> calling a specifica installation of perl directly in their scripts:
> JW >
> JW >#!/usr/local/bin/perl -w
> JW >
> JW >Because we are doing extensive testing with a number of perl 
> installations, I _really_ need to change that to:
> JW >
> JW >#!/usr/bin/env perl -w
> JW >
> JW >The problem is, env won't take the -w. If I leave it off it works fine:
> JW >
> JW >#!/usr/bin/env perl
> JW >
> JW >but as soon as I put the -w back on I get:
> JW >/usr/bin/env: perl -w: No such file or directory
> JW >
> JW >Apparently env thinks "-w" is a binary to execute in addition to perl.
> JW >
> JW >From the man page I think that env _can_ take args:
> JW >
> JW >       env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
> JW >
> JW >But how?
> 
> JW >TA >On Tue, 16 Apr 2002, David Talkington wrote:
> JW >TA >
> JW >TA >> >#!/usr/bin/env perl -w
> JW >TA >
> JW >TA >This will work:
> JW >TA >
> JW >TA >      #! /usr/bin/env - perl -w
> JW >TA >
> JW >TA >You were missing the dash to tell env that everything after should be
> JW >TA >passed on to perl, instead of being a switch for env itself. :)
> JW >
> JW >But I tried that, having got the idea from the man page. This is what I 
> used:
> JW >
> JW >#!/usr/bin/env - perl -w (or #! /usr/bin/env - perl -w )
> JW >
> JW >And this is what I get:
> JW >
> JW >devcp cpbackend2/engine> ./bg_customersubaccountspiderkeyword2 
> --customersubaccountid=14 --seid=1 --remote=self
> JW >/usr/bin/env: invalid option --
> JW >Try `/usr/bin/env --help' for more information.
> JW >devcp cpbackend2/engine>
> JW >
> JW >
> JW >Maybe it's freaking out over the shell arguments, I dunno.
> JW >
> JW >Any more ideas?
> JW >
> 
> JW >JS >On Tue, 16 Apr 2002, JW wrote:
> JW >JS >
> JW >JS >
> JW >JS >Both the man and info (urggh) page say:
> JW >JS >
> JW >JS >SYNOPSIS
> JW >JS >       env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
> JW >JS >
> JW >JS >DESCRIPTION
> JW >JS >       Set each NAME to VALUE in the environment and run COMMAND.
> JW >JS >
> JW >JS >
> JW >JS >So... will it really work like this?
> JW >JS >
> JW >JS >!#/usr/bin/env - perl -w
> JW >JS >
> JW >JS >I thought you'd have to give it something like:
> JW >JS >
> JW >JS >env - PERL=/usr/bin/perl -w
> JW >JS >
> JW >JS >etc?
> JW >JS >
> JW >JS >Probably talking through my hat as usual... ;-)
> JW >
> JW >But that completely defeats the purpose of this exercise, which is to 
> have env find perl (yes, perl is moving around ;-).
> JW >
> JW >Unless it could be:
> JW >
> JW >  env - PERL=`which perl` -w
> JW >
> JW >But that's too wierd, I could hardly belive that.
> TA >On Wed, 17 Apr 2002, Juha Saarinen wrote:
> TA >
> TA >> pts/0 address@hidden:~$ env -i PATH=/usr/bin/ perl -w hello.pl
> TA >> Hello, World!
> TA >
> TA >It works from the command line, but not on a shebang line. 
> 
> 
> TA >Apparently, this will work from the command line:
> TA >
> TA >  env - perl -we 'print "Foo\n"'  
> TA >
> TA >but not from a shell script. Interesting. Not sure what to tell you.
> TA >
> 
> - -- 
> 
> - ----------------------------------------------------
> Jonathan Wilson
> System Administrator
> Clickpatrol.com
> Cedar Creek Software     http://www.cedarcreeksoftware.com
> 
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.0.6 (GNU/Linux)
> Comment: For info see http://www.gnupg.org
> 
> iD8DBQE8vaLMQ5u80xXOLBcRAmSIAJ9cMyHgtfWicnHjCoT1NHgRjPG7rACfTWcd
> 0TU8Z3Lr+z1coj5uuawDIHQ=
> =9EaG
> -----END PGP SIGNATURE-----
> 
> 
> _______________________________________________
> Bug-sh-utils mailing list
> address@hidden
> http://mail.gnu.org/mailman/listinfo/bug-sh-utils



reply via email to

[Prev in Thread] Current Thread [Next in Thread]