文件开头的 #!/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 一起工作呢?
谢谢。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
#! 名为“shebang”,是执行脚本的 Unix 方式。 当你要求操作系统执行一个文件时,它会发现这不是一个普通的 .exe 文件,并且 #! 在开始时
作为一个神奇的标记,指示操作系统执行 #! 之后的命令 并连接该命令,以便
如果 myfile.py 包含
执行该文件与运行
我的 Haskell 知识没有太大区别,则该文件成为该命令的参数。 但对于你的特殊情况,似乎 runghc 命令
只需读取第一行,解析该 #! 上给出的任何参数! 行,将文件的其余部分写入临时文件并在该临时文件上运行 ghc(这将删除第一个留置权 - 请参阅 ghc 源中的 runghc.hs 以获取更多信息。)
如果您想做同样的事情使用 javac,您可以使用与 runghc 相同的方法。
编写一个包装器,它会吃掉文件的第一行,将文件的其余部分写入临时文件并在该文件上运行 javac。
#! 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
executing that file is not very different from running
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.
如果您的文件是 hello.hs,并且第一行是“#!/usr/bin/runghc”,那么 shell 将执行:
第一行基本上告诉 shell 使用什么来运行脚本。
对于 java 示例,第一行应该是运行脚本的可执行文件,而不是编译脚本。
If your file is hello.hs, and the first line is "#!/usr/bin/runghc", then the shell will execute:
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.
这个“技巧”在 Python 和 Perl 中有效,因为
#
在这些语言中开始注释,因此解释器将该行视为注释并忽略它。 所以对于他们来说,这没什么特别的。在 Haskell 中,
#
不会启动注释,因此它通常不起作用。 然而,GHC(也许还有其他实现,如果没记错的话,hugs 也做到了)对于 shebang 行有一个特殊情况。 如果文件的第一行以#!
开头,则将其视为注释。 这种与语言规范的偏差已被准确地纳入到工作中。 它不适用于 javac,因为 shebang 行没有内置特殊情况。
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 makework. It does not work with
javac
because there's no special case built into that for shebang lines.shebang 仅适用于解释性语言......它通常对编译器没有任何意义,在大多数情况下会出错
The shebang only works with interpreted languages....it generally means nothing to a compiler which will error out in most cases
之所以有效,是因为 Python、Perl 和 Haskell 都是解释性语言。 这是指定将运行脚本的解释器的标准 Unix 方式。 Java是一种编译语言,不能用解释器运行。
The reason that this works is because Python, Perl, and apparently Haskell, are all interpreted languages. It is the standard Unix way to designate the interpreter that will run the script. Java is a compiled language, and can't be run with an interpreter.
Javac 是编译器,而不是解释器。
它缺乏交互模式,我相信这就是造成“魔力”的原因。
同样的方法不适用于 GCC,因为它缺乏相同的功能。
例如,dmd(D 编译器)是支持解释的编译器的一个示例,具有这种交互式编辑(#!/usr/bin/dmd -run)。
Javac is a compiler, not an interpreter.
It lacks interactive mode which I believe is what is causing the 'magic'.
The same will not work with GCC since it lacks the same feature.
dmd (The D compiler) for example, is an example of a compiler that supports interpertation has this kind of interactive editing (#!/usr/bin/dmd -run).
它是计算机上用于解释脚本的可执行文件的位置。 Java是编译型语言,因此不需要这样的声明。
此外,重点是它是一个特殊的注释,Java 中的构造是不合法的,因为 # 不是合法的注释标记。 如果这样的构造有意义...但事实并非如此...它看起来像:
//!/usr/local/jdk1.6.0_13/bin/javac
It is the location of the executable on your computer to interpret your script. Java is a compiled language, thus it does not need such a statement.
Furthermore, the point is that it is a special comment, the construction in Java would not be legal in that way as a # is not a legal comment marker. If a construction like that would make sense... which it doesn't... it would look like:
//!/usr/local/jdk1.6.0_13/bin/javac
通过<找到对shebang行的引用 a href="http://en.wikipedia.org/wiki/Shebang_%28Unix%29" rel="nofollow noreferrer">维基百科 但 这篇似乎是更好的文章。 另请参阅“#!” magic - 有关各种 Unix 风格的 shebang 机制的详细信息。
Found this reference to the shebang line through Wikipedia but this seems to be the better article. See also The '#!' magic - details about the shebang mechanism on various Unix flavours.