3

私は最近 scala のプログラミングを始めたばかりで、本「Programming in Scala」(www.artima.com/pins1ed) で、Linux で scala スクリプトを実行する次の方法が紹介されています。

#!/bin/sh
exec scala "$0" "$@"
!#
// Say hello to the first argument
println("Hello, "+ args(0) +"!")

今では長い間 Linux を使用していますが、bash スクリプトは私の専門ではありません。これで、このタイプの scrpt がどのように機能するか (そして美しく機能する) を推測できますが、!# と $@ が正確に何をするのか疑問に思っていました。

すべての助けを前もってありがとう!

4

4 に答える 4

4

確かに美しい。$0"$@"は位置パラメータ ( = C の$0ように command 自体、およびfor )ですが、ファイルに対してどのプログラムを実行するかを認識した場合は、シェルと場合によってはカーネルに通知します。argv[0]argv[1]+"$@"#!*

ここで実際に起こっていることは、シェルが入力読み取りのためにスクリプトを開くことですが、 の時点でexec、入力を scala に転送しますが、ファイル記述子がまだ開いているため、scala は最初から再度読み取る必要はありません。そのため、scala は次の行を読み続けます。

それがどのように機能するかを明確かつ単純に表現したスクリプトを目にすることはめったにありません。

スクリプトを実行するシェルのプロセスを置き換えることに注意してください。execしたがって、シェルは scala になりますが、scala には環境変数と開かれたハンドラーが同じように含まれます。

アップデート

私が間違っていたようです。Scala 自体は全体を読み取りますが、ヘッダー行として認識できるものはスキップします。したがって、これが の本当の目的です!#:

スクリプト ファイルには、存在する場合は無視されるオプションのヘッダーが含まれている場合があります。ヘッダーをフォーマットするには 2 つの方法があります。!# で終わるか、::#! で始まります。::!# で終わります。

于 2013-09-02T09:07:12.920 に答える
4

!#バッシュとは関係ありません。これは Scala 言語の一部です。スクリプト モードで Scala コードから非 Scala ヘッダーを分離します。

于 2013-09-02T09:11:06.857 に答える
2

"$@"すべてのスクリプト引数を表します。

于 2013-09-02T09:05:12.133 に答える
2

「$@」が正確に何をするかについて尋ねました。単語を分割しない方法で引数をスクリプトに渡します。いくつかの例を見てみましょう:

$ cat echowrap
#!/bin/sh
set -x
echo $*
echo $@
echo "$@"

$ ./echowrap oneword 'two words'
+ echo oneword two words
oneword two words
+ echo oneword two words
oneword two words
+ echo oneword 'two words'
oneword two words

最初の例で$*は、echo が 3 つの単語を認識するように入力引数を分割しています。2 番目の例$@は同じように動作します。3 番目の例"$@"は単語分割を行わないため、echo は最初に渡されたものと同じ 2 つの引数を認識します。

もっと役に立つ例を考えてみましょう。スクリプトを次のように呼び出した場合

$ ./scalascript 'Joe Bloggs'

次にorに変更"$@"してみてください。シェルは 2 つの引数を scala に渡し、scala は args(0) と args(1) を認識し、テスト プログラムの出力は異なります。$@$*

于 2013-09-02T10:02:33.687 に答える