19

私は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でどのように機能させるのでしょうか。

ありがとう。

4

8 に答える 8

20

#! 「シバン」という名前で、スクリプトを実行する Unix の方法です。OS にファイルの実行を要求すると、これが通常の .exe ファイルではないことがわかり、#! 最初に #! の後にコマンドを実行するよう OS に指示するマジック マーカーとして機能します。そのコマンドを配線して、このファイルがそのコマンドの引数になるようにします

myfile.py が含まれている場合

#!/usr/bin/python

そのファイルを実行することは、実行することとそれほど変わらない

$ /usr/bin/python myfile.py

私の Haskell の知識は貧弱です。しかし、あなたの特定のケースでは、runghcコマンドは単に最初の行を読み取り、その #! 行、残りのファイルを一時ファイルに書き込み、その一時ファイルで ghc を実行します (最初のリーエンが取り除かれます - 詳細については、ghc ソースの runghc.hs を参照してください)。

javac で同じことをしたい場合は、runghc と同じアプローチを使用できます。ファイルの最初の行を食べ、残りのファイルを一時ファイルに書き込み、そのファイルで javac を実行するラッパーを作成します。

于 2009-07-14T00:16:05.413 に答える
5

ファイルが hello.hs で、最初の行が「#!/usr/bin/runghc」の場合、シェルは次のように実行されます。

/usr/bin/runghc hello.hs

その最初の行は基本的に、スクリプトを実行するために何を使用するかをシェルに指示します。

Java の例では、最初の行は、スクリプトをコンパイルするものではなく、スクリプトを実行する実行可能ファイルである必要があります。

于 2009-07-14T00:08:28.930 に答える
2

私の質問は、なぜ最初の行が無視されるのですか? haskell のコメントは -- で始まりますが、最初の行はまだ無視されているようです。ghciにもロードされます。このトリックは、Python と Perl でも機能します。

「トリック」は Python と Perl で機能し#ます。これらの言語ではコメントが開始されるため、インタープリターはその行をコメントと見なして無視します。だから彼らにとって、それは特別なことではありません。

Haskell では#、コメントを開始しないため、通常は機能しません。ただし、GHC (おそらく他の実装でも、メモリが機能する場合は、hugs もそれを行いました) には、シバン行の特別なケースがあります。ファイルの最初の行が で始まる場合#!、それはコメントとして扱われます。この言語仕様からの逸脱は、正確に組み込むために組み込まれています。

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

仕事。javacシバン行には特別なケースが組み込まれていないため、動作しません。

于 2012-01-19T06:09:08.463 に答える
1

シバンは解釈された言語でのみ機能します....通常、ほとんどの場合エラーになるコンパイラーにとっては何の意味もありません

于 2009-07-14T00:08:47.807 に答える
0

これが機能する理由は、Python、Perl、そして明らかに Haskell がすべてインタープリター型言語であるためです。これは、スクリプトを実行するインタープリターを指定する標準的な Unix の方法です。Java はコンパイル済み言語であり、インタープリターを使用して実行することはできません。

于 2009-07-14T00:09:57.913 に答える
0

Javac はコンパイラーであり、インタープリターではありません。

「魔法」を引き起こしていると私が信じているインタラクティブモードがありません。同じ機能がないため、同じことは GCC では機能しません。

たとえば、dmd (D コンパイラ) は、この種の対話型編集 (#!/usr/bin/dmd -run) をサポートするコンパイラの例です。

于 2009-07-14T00:11:49.313 に答える
0

これは、スクリプトを解釈するためのコンピューター上の実行可能ファイルの場所です。Java はコンパイル済み言語であるため、そのようなステートメントは必要ありません。

さらに、ポイントは、それが特別なコメントであるということです。# は正当なコメント マーカーではないため、Java での構造はそのようには正当ではありません。そのような構造が理にかなっている場合...そうではありません...次のようになります。

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

于 2009-07-14T00:14:40.483 に答える
0

ウィキペディアでシバン行へのこの参照を見つけましたが、これより良い記事のようです。「#!」も参照してください。マジック - さまざまな Unix フレーバーのシバン メカニズムに関する詳細

于 2009-07-14T00:25:08.707 に答える