Шебанг "#!" начинается и "! #" заканчивается?

Я использовал shebang #! некоторое время, и сегодня наткнулся на случай использования, который меня смущает.

Существует несколько способов запуска scala script как

#!/usr/bin/env scala 
println("hello world")

Однако я наткнулся на эту версию shebang

#!/bin/sh
exec scala "$0" "[email protected]"
!#
println("hello world")

Похоже, что это решение в основном вызывает bash во-первых, run exec scala "$0" "[email protected]", где $0 обозначает текущее имя файла, а [email protected] - входные аргументы в позиционном массиве.

Мой вопрос в том, означает ли это, что все между #! и !# может быть выполнено в bash,

#!/bin/sh
exec scala "$0" "[email protected]"
echo "oh Yeah"
!#
println("hello world")

Это не ошибка, но я не дал мне "о да" в stdout, может ли кто-нибудь объяснить мне, что здесь происходит?


update: после реализации !# является scala, я загрузил исходный код scala и понял, что он появляется только в комментарии ScriptRunner.scala, написанная Lex Spoon.

Ответ 1

Строка !# не имеет смысла для оболочки.

Строка #!/bin/sh означает, что script выполняется /bin/sh. Строка exec scala "$0" "[email protected]" вызывает scala, передавая имя script и его аргументы команде scala. Поскольку exec не возвращается, оболочка не видит остальную часть script.

Я не знаю Scala, но я понял, что интерпретатор Scala сам относится ко всему, от строки #! до строки !# в качестве комментария. Затем он запускается с помощью оператора Scala println("hello world").

Короче говоря, !# - это синтаксис Scala, а не синтаксис оболочки (но синтаксис Scala предназначен для использования в оболочке script).

В кратком обзоре Scala Спецификация языка, я не узнал, как это определено. Он упомянул, но не объяснил, в этот вопрос. Вероятно, как замечает chepner 3 комментарий, что это взломать интерпретатор Scala, а не часть фактического синтаксиса языка.

som-snytt нашел код в интерпретаторе 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 "::!#".
   */
...

Но мне интересно, подтверждено ли это.