我一直在使用shebang #!
一段时间,今天遇到了一个令我困惑的用例。
有几种方法可以运行scala脚本,例如
#!/usr/bin/env scala
println("hello world")
然而,我遇到了这个版本的shebang
#!/bin/sh
exec scala "$0" "$@"
!#
println("hello world")
看起来这个解决方案基本上首先调用bash,运行exec scala "$0" "$@"
其中$0
表示当前文件名,$@
是位置数组中的输入参数。
我的问题是否意味着#!
和!#
之间的所有内容都可以在bash中执行,
#!/bin/sh
exec scala "$0" "$@"
echo "oh Yeah"
!#
println("hello world")
它没有错误但是在stdout中没有给我“哦是的”,有人能向我解释这里发生了什么吗?
更新:在认识到!#
是scala之后,我下载了scala的源代码并意识到它只出现在Lex Spoon编写的ScriptRunner.scala部分的评论中。
答案 0 :(得分:9)
!#
行对shell 没有任何意义。
#!/bin/sh
行表示脚本由/bin/sh
执行。 exec scala "$0" "$@"
行调用scala
,将脚本及其参数的名称传递给scala
命令。由于exec
未返回,因此shell不会看到脚本的其余部分。
我不知道Scala,但我的有根据的猜测是,Scala解释器本身将从#!
行到!#
行的所有内容视为注释。然后它开始使用Scala语句println("hello world")
执行。
简而言之,!#
是Scala语法,而不是shell语法(但Scala语法旨在让它在shell脚本中像这样使用)。
快速查看Scala Language Specification,我还没有找到如何定义。在this question中提到但未解释。正如chepner 3的评论所暗示的那样,它可能是Scala解释器中的一个黑客,而不是实际语言语法的一部分。
object ScriptSourceFile {
/** Length of the script header from the given content, if there is one.
* The header begins with "#!" or "::#!" and ends with a line starting
* with "!#" or "::!#".
*/
...
但我想知道它是否有记录。