理解!#和$ @在bash中

时间:2013-09-02 09:02:31

标签: linux bash shell scala

我刚刚开始编写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 个答案:

答案 0 :(得分:3)

确实很漂亮。 $0"$@"是位置参数($0 =命令本身就像C中的argv[0]argv[1]+ "$@"},而{#!* 1}}告诉shell,有时是内核,如果它识别出要为文件执行的程序。

这里发生的事情实际上是shell打开输入读取的脚本,但在exec点,它将输入传递给scala,但scala不必从头开始再读取它因为文件描述符仍然是打开的,所以scala继续在下一行读取。

我很少看到这样做的脚本,只是简单明了地说明了它的功能。

请注意,exec替换了运行脚本的shell的进程,因此它就像shell变为scala,但scala将拥有环境变量并打开处理程序。

<强>更新

看起来我错了。 Scala本身读取整个内容,但跳过它可以看作标题行的内容。所以这是!#

的真正目的

脚本文件可能有一个可选的标头,如果存在则会被忽略。格式化标题有两种方法:以#开头!并以!#结尾,或以::#开头!并以::!#。

结尾

答案 1 :(得分:3)

!#与Bash没有任何关系。它是Scala语言的一部分。它在脚本模式下将非Scala标头与Scala代码分开。

答案 2 :(得分:1)

"$@"表示所有脚本参数。

答案 3 :(得分:1)

你问过什么&#34; $ @&#34;确切地说。它以非字拆分的方式将参数传递给脚本。让我们看一些例子:

$ 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看到三个单词。第二个示例$@的行为相同。第三个例子"$@"没有进行分词,因此echo看到的是与最初传递的2个args相同的。

考虑一个更有用的例子;如果您将脚本称为

$ ./scalascript 'Joe Bloggs'

然后尝试将"$@"更改为$@$*,shell会将两个参数传递给scala,scala会看到args(0)和args(1),以及输出测试程序会有所不同。