В чем смысл! # (Bang-фунт) в оболочке sh/Bash script?
Я хочу понять, как работает этот Scala script:
#!/usr/bin/env bash
exec scala "$0" "[email protected]"
!#
object HelloWorld {
def main(args: Array[String]) {
println("Hello, world! " + args.toList)
}
}
HelloWorld main args
В строке 3, что делает "! #"? Остается ли остаток файла в стандартный ввод программы Scala? Кроме того, "! #" Документирован где угодно?
NB: Самое ближайшее, что я мог найти, хотя это не имеет прямого отношения к вопросу о переполнении стека Зачем вам нужно поставить #!/bin/ bash в начало файла script? (о начале Bash script).
Ответы
Ответ 1
Из исходная документация:
Script файлы могут иметь необязательный заголовок, который игнорируется, если он присутствует. Существует два способа форматирования заголовка: либо С#! и заканчивается на! #, или начиная с:: #! и заканчивается на::! #.
Итак, следующий код - это просто заголовок для Scala script:
#!/usr/bin/env bash
exec scala "$0" "[email protected]"
!#
Ответ 2
Когда я удалил !#
в образце программы в ответ BluesRockAddict, я получаю следующую ошибку на консоли:
ошибка: script файл не закрывает свой заголовок с помощью! # или::! # обнаружена одна ошибка
Из приведенного выше сообщения об ошибке я понял следующие вещи:
-
!#
- тег close для заголовка exec scala "$0" "[email protected]"
, который, вероятно, сообщает Scala, что все, что приходит после !#
, - это код Scala, который должен быть выполнен.
-
!#
можно заменить на ::!#
.
Ответ 3
Основываясь исключительно на экспериментировании (я предполагаю, что это описано где-то):
Начиная с Scala 2.10.0, нестандартный (из POSIX скриптовый POV) фунт-бит (! #) больше не требуется (или разрешается) в среде оболочки POSIX. Следующая одиночная строка работает (но должна быть первой строкой script без начальных пробелов):
#!/usr/bin/env scala
Однако единственный способ предоставить shebang в пакетном файле Windows - обмануть его при вызове Scala с самим собой в качестве первого аргумента. Следовательно, Scala должен знать, где находится последняя строка командного файла, и поэтому требует закрытие::! # Строки. Вот рабочий пример:
::#!
call scala %0 %*
goto :eof
::!#
Исправление: у меня изначально было #!/usr/bin/env scalav (обратите внимание на trailing v), который является моим script для определения свойства "scala.script", добавьте некоторые библиотеки в путь к классам, exec scala '. Таким образом, можно определить имя выполняемого script, хотя scalav должен быть в вашем PATH.