views:

630

answers:

7

It seems to me like the files run the same without that line.

+8  A: 

That is called the shebang line. As the Wikipedia entry explains:

In computing, a shebang (also called a hashbang, hashpling, pound bang, or crunchbang) refers to the characters "#!" when they are the first two characters in an interpreter directive as the first line of a text file. In a Unix-like operating system, the program loader takes the presence of these two characters as an indication that the file is a script, and tries to execute that script using the interpreter specified by the rest of the first line in the file.

See also the Unix FAQ entry.

Even on Windows, where the shebang line does not determine the interpreter to be run, you can pass options to the interpreter by specifying them on the shebang line. I find it useful to keep a generic shebang line in one-off scripts (such as the ones I write when answering questions on SO), so I can quickly test them on both Windows and ArchLinux.

The env utility allows you to invoke a command on the path:

The first remaining argument specifies the program name to invoke; it is searched for according to the PATH environment variable. Any remaining arguments are passed as arguments to that program.

Sinan Ünür
+1: Essential reference material that could have been found with Google. Perfect.
S.Lott
Easy to find with Google - if one knows the keywords (The "shebang line" is essential).
Arafangion
+14  A: 

If you have several versions of Python installed, /usr/bin/env will ensure the interpreter used is the first one on your environment's $PATH. The alternative would be to hardcode something line #!/usr/bin/python or the like -- that's OK but less flexible.

In Unix, an executable file that's meant to be interpreted must indicate what interpreter to use by having a #! at the start of the first line, followed by the interpreter (and any flags it may need); otherwise, I believe the default is /bin/sh.

If you're talking about other platforms, of course, this rule does not apply (but that "shebang line" does no harm, and will help if you ever copy that script to a platform with a Unix base, such as Linux, Mac, etc).

Alex Martelli
Just to add: this applies when you run it in Unix by making it executable (`chmod +x myscript.py`) and then running it directly: `./myscript.py`, rather than just `python myscript.py`.
Craig McQueen
using `env` gives maximum flexibility in that the user can select the interpreter to use by changing the PATH. Often this flexibility is not required though and the downside is that linux for example can't use the script name for the name of the process in `ps` and reverts to "python". When packaging python apps for distros for example I would advise not to use `env`.
pixelbeat
A: 

This is a shell convention that tells the shell which program can execute the script.

#!/usr/bin/env python

resolves to a path to the Python binary.

Frank Krueger
+2  A: 

Technically, in Python, this is just a comment line.

This line is only used if you run the py script from the shell (from the command line). This is know as the "Shebang!" and is used in various situations, not just with Python scripts
Here, it instructs the shell to start [a specific version of] Python (to take care of the rest of the file.)

mjv
+1  A: 

It seems to me like the files run the same without that line.

If so, then perhaps you're running the Python program on Windows? Windows doesn't use that line—instead, it uses the file-name extension to run the program associated with the file extension.

Craig McQueen
He might also be using `$ python myscript.py`.
Sinan Ünür
+4  A: 

Expanding a bit on the other answers, here's a little example of how your command line scripts can get into trouble by incautious use of /usr/bin/env shebang lines:

$ /usr/local/bin/python -V
Python 2.6.4
$ /usr/bin/python -V
Python 2.5.1
$ cat my_script.py 
#!/usr/bin/env python
import json
print "hello, json"
$ PATH=/usr/local/bin:/usr/bin
$ ./my_script.py 
hello, json
$ PATH=/usr/bin:/usr/local/bin
$ ./my_script.py 
Traceback (most recent call last):
  File "./my_script.py", line 2, in <module>
    import json
ImportError: No module named json

The json module doesn't exist in Python 2.5.

One way to guard against that kind of problem is to use the versioned python command names that are typically installed with most Pythons:

$ cat my_script.py 
#!/usr/bin/env python2.6
import json
print "hello, json"

If you just need to distinguish between Python 2.x and Python 3.x, recent releases of Python 3 also provide a python3 name:

$ cat my_script.py 
#!/usr/bin/env python3
import json
print("hello, json")
Ned Deily
+1: Great job illustrating why `/usr/bin/env python` is the right way to go!
jathanism
Hmm, that's not what I got out of that post.
glenn jackman
A: 

Hi,

the use of #!/bin/env (or wherever 'env' exists) is really great but it has one drawback which I have not resolved:

Some scripts might benefit from a switch to the interpreting shell, for example for csh one might want to use 'csh -f' to start faster.

How is this done with env?

!/bin/env csh -f

do not work.

Niclas Olsson