Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 943
Lucky Avatar asked Jul 14 '09 00:07

Lucky


3 Answers

#! 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.

like image 86
nos Avatar answered Oct 29 '22 18:10

nos


If your file is hello.hs, and the first line is "#!/usr/bin/runghc", then the shell will execute:

/usr/bin/runghc hello.hs

That first line basically tells the shell what to use to run the script.

As for the java example, the first line should be the executable that runs the script, not that compiles the script.

like image 24
Tom Dalling Avatar answered Oct 29 '22 17:10

Tom Dalling


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.

The 'trick' works in Python and Perl because # starts a comment in those languages, so the interpreter sees that line as a comment and ignores it. So for them, it's nothing special.

In Haskell, # does not start a comment, so it wouldn't normally work. However, GHC (perhaps also other implementations, if memory serves, hugs did it too) has a special case for shebang lines. If the very first line of a file begins with #!, it is treated as a comment. This deviation from the language specification has been incorporated exactly to make

$ chmod +x hello.hs
$ ./hello.hs

work. It does not work with javac because there's no special case built into that for shebang lines.

like image 43
Daniel Fischer Avatar answered Oct 29 '22 16:10

Daniel Fischer