bash -x引入了奇怪的引号

时间:2014-06-03 10:23:26

标签: bash shell debugging

一个名为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

问题

  1. 为什么双引号会在调试输出中引入单引号?
  2. 为什么调试输出中只有两对单引号,而不是更多或更少?
  3. <小时/> 的修改

    '--config'$1,正如@Hastur所说。

3 个答案:

答案 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)

  1. 它显示了以规范形式解析命令行的方式。由于它在不再进行处理的阶段显示它,因此它使用单引号来表示文字参数。

  2. 引号仅包含包含需要引用的特殊字符的参数。第一个参数在hello,--config之间有一个空格,因此需要引用它。最后一个参数包含;space,需要引用。但8888--match没有任何特殊字符,因此不需要引号。

  3. 当您将$@置于双引号内时,它会将每个原始参数转换为单独的参数。但是你在引号中还有额外的文字。它之前的字符串被放到$1的开头,字符串被放到最后一个参数的末尾。

  4. 通常你只需写"$@"。我想不出你将$@放在另一个字符串中的原因就像你一样。