Use /usr/bin/env python ... why?

Tim Cargile tecargile at hotmail.com
Thu Jan 9 22:29:15 EST 2003


"Steve Holden" <sholden at holdenweb.com> wrote in message news:<wVlT9.30621$u9.8151 at fe08>...
> Tim Cargile" <tecargile at hotmail.com> wrote ...
> > There was a previous thread on this that referenced a python.org FAQ
> > that I thought was incomplete.  As a casual observer I would
> > like to submit the following - in the order of most to least efficient
> > and least to most flexible (perhaps):
> >
> > Use '#!/usr/bin/python' when:
> >
> >       The location of 'python' can be or is guaranteed to
> >       be '/usr/bin' AND one one wants the least execution
> >       overhead AND does not wish to alter the 'python' runtine
> >       environment. Or when PATH searching is not possible
> >       for some reason (restricted environment - cron job).
> >
> > Use '#!/python' when:
> >
> Don't think you want a leading slash in there, old chap. Very few people
> actually put the interpreter in the root directory (though of course we all
> know that's where it belongs :-)

Yes.  A Pythonian slip I guess.  And '#!python appears to work on my
Cygwin environment ONLY when the module is executed through two layers
of bash.  The final execution shell does an eval exec.  I does not work
on SUN either so I guess any attempt at '#command' is not tenable.

> 
> >       The location of 'python' cannot be guaranteed to be 'usr/bin'
> >       (or any other locaton) AND one one is willing to incur the
> >       overhead of a PATH search AND a PATH search is possible
> >       AND does not wish to alter the 'python' runtine environment.
> >       I have tested this under Cygin with both 'ksh' and 'python'
> >       and it works as one would expect.
> >
> That's as may be, but (for example) Red Hat 8.0 certainly won't have any of
> that. I get the same result whether the slash is included or not:
>
 
Again.  You are correct.  I seem to have discovered a Cygwin 'feature'.
that works only one situation. I tested '#!ksh and it works on Cygin
ONLY when the shell is executed from a parent shell.  This is similar
to the successful observed launching of the *.py module with '#!python
from a shell wrapper.  I wonder if this is true for Linux/UNIX?  

> [sholden at munger sholden]$ cat pytest
> #!python
> 
> print "Hello";
> 
> [sholden at munger sholden]$ ls -l pytest
> -rwxrwxr-x    1 sholden  sholden        26 Jan  9 16:28 pytest
> [sholden at munger sholden]$ ./pytest
> bash: ./pytest: python: bad interpreter: No such file or directory
> [sholden at munger sholden]$ python
> Python 2.2.1 (#1, Aug 30 2002, 12:15:30)
> [GCC 3.2 20020822 (Red Hat Linux Rawhide 3.2-4)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
> >>>
> 
> "python pytest" works just fine, of course.
> 
> > Use '#!/usr/bin/env python' when:
> >
> >       The location of 'env' is guaranteed to be '/usr/bin'
> >       AND when it is desired to alter the environment prior
> >       to execution of 'python' AND when one is willing to
> >       incur the overhead (not as minimal as a PATH search)
> >       of starting 'env' and one cannot guarantee the location
> >       of 'python' and one is willing to incur the (minimal)
> >       overhead of a PATH search for 'python'.  Incidentally,
> >       I could measure the performance hit (in 10ths of seconds)
> >       of running with the startup overhead of 'env' on my
> >       900 Mhz laptop under Cygwin.  On a System with 2000 users
> >       (not even my laptop) it might make a difference).
> >
> > Use '#!env python' when:
> >
> >       The location of 'env' cannot be guaranteed AND the
> >       location of 'python' cannot be guaranteed AND
> >       it is desired to alter the environment prior
> >       to execution of 'python' AND one is willing to
> >       incur the overhead (admittedly minimal) of searching
> >       the PATH for 'env' AND starting 'env' (not so minimal)
> >       and serching the PATH for 'python'.  A lot of 'AND's in this one.
> >
> I think this will have the same problems outlined above for "python".

Yes.  I do on Cygin when the *.py is launched directly from my command-line
shell.  But, as in the '#!python test, not when launched from a parent
shell.  This is through a wrapper that does an 'eval exec'.  This is
also true for shell scripts.  The '#!ksh' works when the shell is
launched from a parent shell which IS NOT the command-line shell.

> 
> > It appears as though the PRIMARY intent of the 'env' utility
> > is to alter the environment - not force a PATH search for the
> > executable.  I have never seen a "#!" line that actually altered
> > the environment.  Has anyone?
> >
> > Oh well, at least I have not seen these:
> >
> >  #!env /usr/bin/python
> >
> >    and
> >
> > #!/usr/bin/env /usr/bin/python
> >
> > These works also, but have yet to observe them in the wild.
> >
> > I'm wondering why I see so many (like 100%) '#!/usr/bin/env python'
> > lines ... in the Cygwin release, at least.  I don't believe this
> > is a religious issue.  It is simple mechanics/logic.  Computers
> > are only machines ... except for the UNIVAC ... it was God.
> >
> Mostly you see it because it's about the most likely to succeed, I suspect.
> Sure, it has problems, but then what doesn't?
>

Well put.  I've come to the same conclusion.  The '#!/usr/bin/env python'
has the greatest success potential, but with a large performance hit.
I can see why it is the convention.  I/we have yet to determine if the 'env'
command remains resident (and idle) while 'python' runs.  It appears
to because it advertises that it will return the status from the
launched utility (SUN env(1)) manual page.  Even though a 'ps' could not
see it.  I did not personally run this test (SUN platform).  I'm not
drawing any more conclusions from my Cygin experience.

Incidentally, there seems to be a problem with actually specifying
a 'name=value' argument on the she-bang line on Cygwin and, possibly,
SUN.  It hangs, but I don't have all the symptom parameters yet.
a 32-bye limit for line storage has been mentioned in other threads,
but I'm hesitant to draw any conclusions from just Cygin observations.
It would be very useful, I would think, to have much more than 32 ...
if there is such a limit.

Still, even if it doesn't (somehow) remain in wait state for the
'python' completion, I would go for the '#!/{FULLPATH}/python' approach
in situations where control of its location was guaranteed.

As I believe another contributor has noted, this can be dealt with by
automated means.  It's trivial if a formal make/release for python
modules is done.  The 'make' rules could easily apply the first line
based upon desired platform during the 'prep' phase (all target) of
the make.

I already do this with shell script makes.  The shell source modules
(*.sh / *.ksh, etc) are not even checked-in to Version Control
with the she-bang line in place because it's not as configurable
or reliable to have them hard-coded.

But the CM aspects of python source vs executables is the subject
of another thread.

Much appreciate your comments.

 
> regards




More information about the Python-list mailing list