给出以下语法:
x=(-a 2);echo "${x[@]}";x=(-e 2 -e); echo "${x[@]}"
Run Code Online (Sandbox Code Playgroud)
输出:
-a 2
2 -e
Run Code Online (Sandbox Code Playgroud)
期望的输出
-a 2
-e 2 -e
Run Code Online (Sandbox Code Playgroud)
为什么会这样?我该如何解决?
Mic*_*pat 11
printf "%s\n" "${x[*]}"
Run Code Online (Sandbox Code Playgroud)
echo
需要3个选项:
$ help echo
[…]
Options:
-n do not append a newline
-e enable interpretation of the following backslash escapes
-E explicitly suppress interpretation of backslash escapes
Run Code Online (Sandbox Code Playgroud)
所以,如果你运行:
$ echo -n
$ echo -n -e
$ echo -n -e -E
Run Code Online (Sandbox Code Playgroud)
你一无所获.即使你将每个选项都放在引号中,它仍然看起来与bash相同:
$ echo "-n"
$ echo "-n" "-e"
Run Code Online (Sandbox Code Playgroud)
最后一个命令运行echo
两个参数:-n
和-e
.现在将其与:
$ echo "-n -e"
-n -e
Run Code Online (Sandbox Code Playgroud)
我们所做的是echo
用一个参数运行:-n -e
.由于bash不识别(组合)选项-n -e
,它最终会像我们想要的那样回应终端的单个参数.
在第二种情况下,数组x
以元素开头-e
.在bash扩展数组后${x[@]}
,您正在有效地运行:
$ echo "-e" "2" "-e"
2 -e
Run Code Online (Sandbox Code Playgroud)
由于第一个参数是-e
,它被解释为一个选项(而不是回显到终端),正如我们已经看到的那样.
现在将其与其他样式的数组扩展进行对比${x[*]}
,它有效地执行以下操作:
$ echo "-e 2 -e"
-e 2 -e
Run Code Online (Sandbox Code Playgroud)
bash看到了单个参数-e 2 -e
- 因为它不认识到这是一个选项 - 它会将参数回显给终端.
请注意,${x[*]}
样式扩展通常不安全.请看以下示例:
$ x=(-e)
$ echo "${x[*]}"
Run Code Online (Sandbox Code Playgroud)
即使我们希望-e
得到回应,也没有任何印刷品.如果你一直在关注,你已经知道为什么会这样.
解决方案是转义echo
命令的任何参数.不幸的是,与其他提供某种说法的命令不同,"嘿!以下参数不应被解释为选项 "(通常是--
参数),bash不提供这样的转义机制echo
.
幸运的是,有一个printf
命令,它提供了所echo
提供功能的超集.因此我们得出了解决方案:
printf "%s\n" "${x[*]}"
Run Code Online (Sandbox Code Playgroud)