What does "#!/usr/bin/env python" do?

P

Parzival

I am a now immigrant to Linux from (the old country)
Can someone explain what the line:

#!/usr/bin/env python

at the start of a python script does? All my reading of
bash and env manpages would lead me to believe that

#!python

is equivalent to the first line, but not speaking well the
language am I, so here the question am I asking.
 
F

Francis Avila

Parzival said:
I am a now immigrant to Linux from (the old country)
Can someone explain what the line:

#!/usr/bin/env python

at the start of a python script does? All my reading of
bash and env manpages would lead me to believe that

#!python

is equivalent to the first line, but not speaking well the
language am I, so here the question am I asking.

Not quite. Bash (and I think most borne-ish shells) does not check the path
for hash-bangs, but expects an absolute pathname. Now, the location of
python can vary widely, so we can't use an absolute pathname. We could do
'/bin/sh -c python', but 1) hash-bangs only pass a single "word" as argument
(only '-' of '-c' would be passed) 2) that would start an unnecessary
subshell.

Hence, /usr/bin/env. It's almost always there, it looks in the path, it
doesn't start a subshell, and it doesn't need extra options to execute the
command. Pretend it's windows' "start".
 
H

Hallvard B Furuseth

Parzival said:
I am a now immigrant to Linux from (the old country)
Can someone explain what the line:

#!/usr/bin/env python

at the start of a python script does? All my reading of
bash and env manpages would lead me to believe that

#!python

is equivalent to the first line, but not speaking well the
language am I, so here the question am I asking.

At least on the operating systems I have checked, #! must be followed by
the full pathname of a program. It does not search $PATH for it.

'/usr/bin/env python' searches $PATH for python and runs it.
(Usually env is used to set some environment variables for a program,
e.g. 'env PYTHONPATH=whatever python', but one need not specify any
environment variables.)

Since env is (almost?) always in /usr/bin, while python can be installed
God-knows-where, that is more portable than writing #!/local/bin/python
or #!/usr/bin/python or whatever.
 
P

Parzival

nospam said:
Since env is (almost?) always in /usr/bin, while python can be installed
God-knows-where, that is more portable than writing #!/local/bin/python
or #!/usr/bin/python or whatever.

That clarifies that! Thanks.

Followup question: I am using Mandrake 9.1, and it installs Python 2.2. I
have installed Python 2.3. Somewhere I read that Mandrake NEEDS Python 2.2
to work, I cannot just remove it, nor can I replace it with 2.3, as this
might be incomptible with some Mandrake Python script requirements.

It further tuns out that I have no control over the placement of entries
in PATH, so that my .bash_profile login script which adds /usr/local/bin to
the PATH, wherein are "python", "python2.3" and "idle", does not have
precedence over the Mandrake installed /usr/bin, wherein are "python" and
"idle". The result is that I must type "python2.3 myscript.py" or
"/usr/local/bin/idle myscript.py", and the just explained "#!/usr/bin/env
python" at the start of scripts always resolves in favour of the Mandrake
installed Python, not my own current version.

I would like my personal installation of Python to be the default and
convenient version, i.e. "./Myscript.py" "python MyScript.py" and "idle"
should resolve that instead of the system version. Is there a good way to
accomplish this?
 
E

Erik Max Francis

Parzival said:
It further tuns out that I have no control over the placement of
entries
in PATH, so that my .bash_profile login script which adds
/usr/local/bin to
the PATH, wherein are "python", "python2.3" and "idle", does not have
precedence over the Mandrake installed /usr/bin, wherein are "python"
and
"idle". The result is that I must type "python2.3 myscript.py" or
"/usr/local/bin/idle myscript.py", and the just explained
"#!/usr/bin/env
python" at the start of scripts always resolves in favour of the
Mandrake
installed Python, not my own current version.

Yes, unfortunately this is the fault of the #!/usr/bin/env solution
(neglecting that in very rare cases env may not be located in /usr/bin).
If multiple Python interpreters are installed, or the same script are
run with rather different environments, then it's hard to say which
interpreter will get caught. For instance, cron jobs often run with
PATH=/bin:/usr/bin only, in which case they wouldn't ever find a python
in /usr/local/bin, unless you told it to do so.
I would like my personal installation of Python to be the default and
convenient version, i.e. "./Myscript.py" "python MyScript.py" and
"idle"
should resolve that instead of the system version. Is there a good way
to
accomplish this?

The best way to do it for your use is to put the place where you want it
found first in your PATH, or invoke the specific interpreter you want
directly.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top