Shebang"#!" 开始,"!#"结束?

B.M*_*.W. 10 bash shell scala shebang

我一直在使用shebang #!,今天遇到了一个令我困惑的用例.

有几种方法可以运行scala脚本

#!/usr/bin/env scala 
println("hello world")
Run Code Online (Sandbox Code Playgroud)

但是,我遇到了这个版本的shebang

#!/bin/sh
exec scala "$0" "$@"
!#
println("hello world")
Run Code Online (Sandbox Code Playgroud)

看起来像该溶液基本上首先调用的bash,运行exec scala "$0" "$@"在那里$0表示当前的文件名和$@处于位置阵列输入参数.

我的问题是,这意味着什么之间#!!#可以在bash中执行,

#!/bin/sh
exec scala "$0" "$@"
echo "oh Yeah"
!#
println("hello world")
Run Code Online (Sandbox Code Playgroud)

它并没有错误,但没有给我在标准中的"哦是啊",任何人都可以向我解释这里发生了什么?


更新:在实现!#scala 之后,我下载了scala的源代码并意识到它只出现在Lex Spoon编写的ScriptRunner.scala部分的注释中.

Kei*_*son 9

!#对shell没有意义.

#!/bin/sh行表示脚本由执行/bin/sh.该exec scala "$0" "$@"行调用scala,将脚本的名称及其参数传递给scala命令.由于exec不返回,shell不会看到脚本的其余部分.

我不知道Scala,但我的有根据的猜测是,Scala解释器本身将从#!行到!#行的所有内容视为注释.然后它开始使用Scala语句执行println("hello world").

简而言之,!#就是Scala语法,而不是shell语法(但Scala语法旨在让它在shell脚本中像这样使用).

快速浏览一下Scala语言规范,我还没有发现它是如何定义的.在这个问题中提到但未解释.正如chepner 3的评论所暗示的那样,它可能是Scala解释器中的一个黑客,而不是实际语言语法的一部分.

SOM-snytt发现在实现这一斯卡拉解释器的代码在这里:

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 "::!#".
   */
...
Run Code Online (Sandbox Code Playgroud)

但我想知道它是否有记录.

  • 似乎是解释器本身的黑客,因为shebang本身不是Scala中的评论. (3认同)