sh / Bash shell脚本中的#(bang-pound)是什么意思?

时间:2012-04-08 04:39:22

标签: bash shell scala command-line

我想了解这个Scala脚本的工作原理:

#!/usr/bin/env bash
exec scala "$0" "$@"
!#
object HelloWorld {
    def main(args: Array[String]) {
        println("Hello, world! " + args.toList)
    }   
}
HelloWorld main args

第3行,“!#”在做什么?然后文件的其余部分被送到Scala程序的standard input吗?还有,'!#'记录在哪里?

注意:我能找到的最接近的东西,虽然它没有任何直接相关性,但Stack Overflow问题 Why do you need to put #!/bin/bash at the beginning of a script file? (关于Bash脚本的开头)

3 个答案:

答案 0 :(得分:18)

来自the original documentation

  

脚本文件可能有一个可选标头,如果存在则会被忽略。格式化标题有两种方法:以#开头!并以!#结尾,或以::#开头!并以::!#。

结尾

因此,以下代码只是Scala脚本的标题:

#!/usr/bin/env bash
exec scala "$0" "$@"
!#

答案 1 :(得分:2)

当我在BluesRockAddict's answer中删除示例程序中的!#时,我在控制台上收到以下错误:

  

错误:脚本文件没有用!#或::!#关闭它的标题   找到一个错误

从上面的错误消息中,我理解了以下内容:

  1. !#是标头exec scala "$0" "$@"的关闭标记,它可能告诉Scala !#之后的任何内容都是要执行的Scala代码。
  2. !#可以替换为::!#

答案 2 :(得分:2)

纯粹基于实验(我假设在某处描述):

从Scala 2.10.0开始,POSIX shell环境中不再需要非标准(来自POSIX脚本POV)pound-bang(!#)。以下单行有效(但必须是脚本的第一行,没有前导空格):

#!/usr/bin/env scala

但是,在Windows批处理文件中提供shebang的唯一方法是欺骗它将自己作为第一个参数调用Scala。因此,Scala需要知道批处理文件的最后一行在哪里,因此需要关闭::!#行。这是一个有效的例子:

::#!
call scala %0 %*
goto :eof
::!#

更正:我最初有#!/ usr / bin / env scalav(注意尾随v),这是我的脚本定义属性“scala.script”,在“exec scala”本身之前添加一些库到类路径。这样就可以确定正在执行的脚本的名称,尽管scalav必须在你的PATH中。