一个名为1.sh的简单bash脚本:
#!/bin/bash -x
echo "hello, $@; "
运行时:
$ ./1.sh --config 8888 --match 2
输出结果为:
+ echo 'hello, --config' 8888 --match '2; '
hello, --config 8888 --match 2;
'--config'
是$1
; 8888
是$2
; --match
是$3
; 2
为$4
。
问题
<小时/> 的修改
'--config'
是$1
,正如@Hastur所说。
答案 0 :(得分:3)
奇怪的引号只不过是你在特殊变量@
扩展之前和之后都有字符串的结果。实际上,任何数组的行为都是正确的。
当你说:
echo "foo $@ bar"
然后foo
被解释为第一个位置参数的一部分,bar
被解释为最后一个位置参数的一部分。
以下示例更好地说明了这一点:
$ foo=(one two three)
+ foo=(one two three)
$ echo "${foo[@]}"
+ echo one two three
one two three
$ echo "${foo[@]} four"
+ echo one two 'three four'
one two three four
$ echo "zero ${foo[@]}"
+ echo 'zero one' two three
zero one two three
# Lets see how the resulting array is actually formed as in your example
$ for i in "zero ${foo[@]} four"; do echo $i; done
+ for i in '"zero ${foo[@]} four"'
+ echo zero one
zero one
+ for i in '"zero ${foo[@]} four"'
+ echo two
two
+ for i in '"zero ${foo[@]} four"'
+ echo three four
three four
答案 1 :(得分:1)
您可能需要的是$*
而不是$@
。差异在Bash manual:
<强> * 强>
从一个开始扩展到位置参数。当扩展发生在双引号内时,它会扩展为单个单词 每个参数的值由第一个字符分隔 IFS特殊变量。也就是说,&#34; $ *&#34;相当于&#34; $ 1c $ 2c ...&#34;, 其中c是IFS变量值的第一个字符。如果 IFS未设置,参数由空格分隔。如果IFS为null, 参数连接时没有插入分隔符。
<强> @ 强>
从一个开始扩展到位置参数。当扩展发生在双引号内时,每个参数都扩展为a 单词。也就是说,&#34; $ @&#34;相当于&#34; $ 1&#34; &#34; $ 2#34; ...。如果 双引号扩展发生在一个单词中, 扩展了 第一个参数与原始的开头部分连接在一起 单词 ,最后一个参数的 扩展与最后一个参数连接 原始单词的一部分 。没有位置参数时 &#34; $ @&#34;并且$ @扩展为空(即,它们被删除)。
答案 2 :(得分:0)
它显示了以规范形式解析命令行的方式。由于它在不再进行处理的阶段显示它,因此它使用单引号来表示文字参数。
引号仅包含包含需要引用的特殊字符的参数。第一个参数在hello,
和--config
之间有一个空格,因此需要引用它。最后一个参数包含;
和space
,需要引用。但8888
和--match
没有任何特殊字符,因此不需要引号。
当您将$@
置于双引号内时,它会将每个原始参数转换为单独的参数。但是你在引号中还有额外的文字。它之前的字符串被放到$1
的开头,字符串被放到最后一个参数的末尾。
通常你只需写"$@"
。我想不出你将$@
放在另一个字符串中的原因就像你一样。