15

I want to understand how this Scala script works:

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

On line 3, what is "!#" doing? Is the remainder of the file then fed to standard input of the Scala program? Also, is '!#' documented anywhere?

NB: The nearest thing I could find, although it is not directly relevant in any way is Stack Overflow question Why do you need to put #!/bin/bash at the beginning of a script file? (about the beginning of a Bash script).

4

3 回答 3

18

原始文档

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

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

#!/usr/bin/env bash
exec scala "$0" "$@"
!#
于 2012-04-08T04:48:04.580 回答
2

Based purely on experimentation (I assume this is described somewhere):

Beginning with Scala 2.10.0, the non-standard (from a POSIX scripting POV) pound-bang (!#) is no longer required in a POSIX shell environment. The following single line works (but must be the first line of the script, with no leading spaces):

#!/usr/bin/env scala

However, the only way to provide a shebang in a windows batch file is to trick it into calling Scala with itself as the first argument. Consequently, Scala needs to know where the last line of the batch file is, and therefore requires the closing ::!# line. Here's a working example:

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

Correction: I originally had #!/usr/bin/env scalav (notice the trailing v), which is my script to define property "scala.script", add some libraries to the classpath, before 'exec scala' itself. That way it's possible to determine the name of the script that is being executed, although scalav must then be in your PATH.

于 2013-02-13T19:40:14.097 回答
2

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

错误:脚本文件没有用 !# 或 ::!# 关闭其标题 发现一个错误

从上面的错误信息中,我明白了以下几点:

  1. !#是 header 的结束标记exec scala "$0" "$@",它可能告诉 Scala 后面!#的内容是要执行的 Scala 代码。
  2. !#可以替换为::!#
于 2012-04-08T06:20:15.903 回答