Well, consider these scripts:
Code:
jc@jcmain:~/scripts$ cat small_script_one.sh
#!/usr/bin/env bash
echo "hello world"
jc@jcmain:~/scripts$ cat small_script_two.sh
echo "hello world"
One Has the shabang on the top, the other doesn't. When I run them both as per:
Code:
jc@jcmain:~/scripts$ bash small_script_one.sh
hello world
jc@jcmain:~/scripts$ bash small_script_two.sh
hello world
They both output the same; however if I run the file command on the two of them:
Code:
jc@jcmain:~/scripts$ file small_script_one.sh
small_script_one.sh: a bash script text executable
jc@jcmain:~/scripts$ file small_script_two.sh
small_script_two.sh: ASCII text
We see that they're both different. This is because when you execute the scripts they check the top line to see what interpreter to run the code in. Now yes, both of those will run as ./<script> because they both contain a bash command, but suppose I have a file as:
Code:
jc@jcmain:~/scripts$ cat small_script.py
import time
print time.asctime()
and try the same? Well, we know it is a python script, and passing it to python is fair enough:
Code:
jc@jcmain:~/scripts$ python small_script.py
Mon Mar 15 12:05:33 2010
But what happens if we make it executable?
Code:
jc@jcmain:~/scripts$ chmod +x small_script.py
jc@jcmain:~/scripts$ ./small_script.py
./small_script.py: line 1: import: command not found
./small_script.py: line 2: syntax error near unexpected token `('
./small_script.py: line 2: `print time.asctime()'
Because the shabang is missing it doesn't know how to interpret it.
So basically, we put the shabang in because when we make it executable, for ease of use, we need to tell it how to run. If that code had a shabang in, then it works perfectly
Code:
jc@jcmain:~/scripts$ cat small_script.py
#!/usr/bin/env python
import time
print time.asctime()
jc@jcmain:~/scripts$ chmod +x small_script.py
jc@jcmain:~/scripts$ ./small_script.py
Mon Mar 15 12:08:06 2010
And so on.
Make sense? Or did I explain that badly?