Что означает #! / Usr / bin / ... в начале файла? - PullRequest
16 голосов
/ 14 июля 2009

Я могу сделать что-то подобное в Haskell:

#!/usr/bin/runghc
main=putStrLn "Hello World"

Тогда я могу запустить его с ./hello.hs

Мой вопрос: почему первая строка игнорируется? Комментарии в haskell начинаются с --, но первая строка все еще игнорируется. Он даже загружается в GHCI. Трюк также работает с Python и Perl.

Но когда я делаю что-то подобное в Java:

#!/usr/local/jdk1.6.0_13/bin/javac
...

Javac выдает ошибку компилятора.

Так как же это работает и как заставить его работать с Java?

Спасибо.

Ответы [ 8 ]

18 голосов
/ 14 июля 2009

#! называется " shebang " и представляет собой способ выполнения сценариев в Unix. Когда вы попросите ОС выполнить файл, она поймет, что это не обычный файл .exe, а символ #! в начале служит волшебным маркером, который инструктирует ОС выполнять команду после #! и связать эту команду так, чтобы этот файл стал аргументом этой команды

, если myfile.py содержит

#!/usr/bin/python

выполнение этого файла мало чем отличается от запуска

$ /usr/bin/python myfile.py

Мои знания Хаскелла плохие. Но для вашего конкретного случая, кажется, команда runghc просто читает первую строку, анализирует любые аргументы, приведенные на этом #! строка, записывает оставшуюся часть файла во временный файл и запускает ghc для этого временного файла (для которого будет удален первый залог; для получения дополнительной информации см. runghc.hs в источниках ghc.)

Если вы хотите сделать то же самое с javac, вы можете использовать тот же подход, что и runghc. Напишите обертку, которая поедает первую строку файла, записывает оставшуюся часть файла во временный файл и запускает для этого файла javac.

5 голосов
/ 14 июля 2009

Если ваш файл - hello.hs, а первая строка - "#! / Usr / bin / runghc", то оболочка выполнит:

/usr/bin/runghc hello.hs

Эта первая строка в основном говорит оболочке, что использовать для запуска скрипта.

Что касается примера Java, первая строка должна быть исполняемым файлом, который запускает сценарий, а не компилирует сценарий.

2 голосов
/ 19 января 2012

Мой вопрос: почему первая строка игнорируется? Комментарии в haskell начинаются с - но первая строка все еще игнорируется. Он даже загружается в GHCI. Трюк также работает с Python и Perl.

«Трюк» работает в Python и Perl, потому что # начинает комментарий на этих языках, поэтому интерпретатор видит эту строку как комментарий и игнорирует ее. Так что для них в этом нет ничего особенного.

В Haskell, # не запускает комментарий, поэтому обычно он не работает. Тем не менее, GHC (возможно, также другие реализации, если память служит, обнимашки тоже это делали) имеет особый случай для линий Шебанга. Если самая первая строка файла начинается с #!, он рассматривается как комментарий. Это отклонение от спецификации языка было включено именно для того, чтобы сделать

$ chmod +x hello.hs
$ ./hello.hs

работа. Он не работает с javac, потому что нет особого случая, встроенного в это для линий Шебанга.

1 голос
/ 14 июля 2009

Shebang работает только с интерпретированными языками .... это вообще ничего не значит для компилятора, который в большинстве случаев выдаст ошибку

0 голосов
/ 14 июля 2009

Это местоположение исполняемого файла на вашем компьютере для интерпретации вашего скрипта. Java - это скомпилированный язык, поэтому он не нуждается в таком утверждении.

Кроме того, дело в том, что это специальный комментарий, конструкция в Java не будет таким образом законной, поскольку # не является допустимым маркером комментария. Если бы подобная конструкция имела смысл ... а это не так ... она бы выглядела так:

//!/usr/local/jdk1.6.0_13/bin/javac

0 голосов
/ 14 июля 2009

Javac - это компилятор, а не интерпретатор.

В нем отсутствует интерактивный режим, который, по моему мнению, и является причиной "магии". То же самое не будет работать с GCC, так как в нем отсутствует та же функция.

Например, dmd (компилятор D) - это пример компилятора, который поддерживает интерпретацию, имеет такой вид интерактивного редактирования (#! / Usr / bin / dmd -run).

0 голосов
/ 14 июля 2009

Причина, по которой это работает, заключается в том, что Python, Perl и, по-видимому, Haskell - все интерпретируемые языки. Это стандартный способ Unix назначить интерпретатор, который будет запускать сценарий. Java является скомпилированным языком и не может быть запущен с интерпретатором.

...