#!/ usr / bin / …在文件开头是什么意思?

我可以在Haskell中做这样的事情:

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

然后我可以运行./hello.hs

我的问题是,为什么第一行被忽略? 在haskell的评论开始--但第一行似乎仍然被忽略。 它甚至加载在ghci中。 这个技巧也适用于Python和Perl。

但是当我在Java中做类似的事情时:

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

Javac给我一个编译器错误。

那么这是如何工作的,我将如何使它与Java一起工作呢?

谢谢。

#! 被命名为“ shebang ”,是一种执行脚本的Unix方式。 当你要求操作系统执行一个文件时,会发现这不是一个普通的.exe文件,#! 在开始时作为魔术标记,指示操作系统在#!后执行命令。 并接线该命令,以便该文件成为该命令的参数

如果myfile.py包含

 #!/usr/bin/python 

执行该文件与运行没有太大区别

 $ /usr/bin/python myfile.py 

我的Haskell知识很差。 但是对于你的特殊情况,似乎runghc命令只是读取第一行,解析给出的任何参数#! 将剩余的文件写入一个临时文件,然后在该临时文件上运行ghc(将删除第一个留置码 – 请参阅ghc源码中的runghc.hs以获取更多信息)。

如果你想用javac做同样的事情,你可以使用和runghc一样的方法。 编写一个包装文件,该文件的第一行,将其余文件写入临时文件并在该文件上运行javac。

如果你的文件是hello.hs,并且第一行是“#!/ usr / bin / runghc”,那么shell将执行:

 /usr/bin/runghc hello.hs 

第一行基本上告诉shell用什么来运行脚本。

至于java的例子,第一行应该是运行脚本的可执行文件,而不是编译脚本。

我的问题是,为什么第一行被忽略? 在haskell的评论开始 – 但第一行似乎仍然被忽略。 它甚至加载在ghci中。 这个技巧也适用于Python和Perl。

“技巧”在Python和Perl中起作用,因为#用这些语言开始注释,所以解释器将该行视为注释并忽略它。 所以对他们来说,没什么特别的。

在Haskell中, #不会开始注释,所以它通常不会正常工作。 然而,GHC(也许还有其他的实现,如果内存是服务的,拥抱也是如此)对于shebang行来说有一个特殊的情况。 如果文件的第一行以#!开头 ,它被视为评论。 这与语言规范的偏离已经完全合并

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

工作。 它不能和javac工作,因为没有特殊的情况为shebang行javac

shebang仅适用于解释型语言….对于大多数情况下会出错的编译器来说,这通常没有任何意义

这个原因是因为Python,Perl和Haskell显然都是解释型语言。 这是标准的Unix方法来指定将运行脚本的解释器。 Java是一种编译语言,不能与解释器一起运行。

Javac是一个编译器,而不是解释器。

它缺乏互动模式,我相信是什么造成了“魔术”。 GCC也不能使用,因为它缺少相同的功能。

例如dmd(D编译器)就是一个支持interpertation的编译器的例子,有这种交互式编辑(#!/ usr / bin / dmd -run)。

这是您的计算机上的可执行文件的位置解释您的脚本。 Java是一种编译语言,因此它不需要这样的语句。

此外,重点在于这是一个特别的评论,在Java中的构建不会是合法的,因为#不是一个法律评论标记。 如果像这样的建筑是有意义的……它不会……它看起来像:

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

通过维基百科发现这个参考shebang线 ,但这似乎是更好的文章 。 另见'#!' 魔术 – 关于各种Unix风格的shebang机制的细节 。