What does #!/usr/bin/... at the start of a file mean?

Lucky picture Lucky · Jul 14, 2009 · Viewed 11.5k times · Source

I can do something like this in Haskell:

#!/usr/bin/runghc
main=putStrLn "Hello World"

Then I can run it with ./hello.hs

My question is, why is the first line ignored? Comments in haskell start with -- but the first line still seems to be ignored. It even loads in ghci. The trick also works with Python and Perl.

But when I do something similar in Java:

#!/usr/local/jdk1.6.0_13/bin/javac
...

Javac gives me a compiler error.

So how does this work and how would I get it to work with Java?

Thanks.

Answer

nos picture nos · Jul 14, 2009

#! is named "shebang" and is a Unix way of executing scripts. When you ask the OS to execute a file it'll figure out that this is not a normal .exe file, and the #! at the start serves as a magic marker which instructs the OS to execute the command after the #! and wiring up that command so this file becomes an argument of that command

if myfile.py contains

#!/usr/bin/python

executing that file is not very different from running

$ /usr/bin/python myfile.py

My Haskell knowledge is poor. But for your particular case it seems the runghc command simply reads the first line, parses any arguments given on that #! line, writes the rest of the file to a temporary file and runs ghc on that temp file(which will have the first lien stripped out - see runghc.hs in the ghc sources for more info.)

If you wanted to do the same thing with javac you could use the same approach as runghc. Write a wrapper, that eats the first line of the file, writes the rest of the file to a temp file and runs javac on that file.