Shell脚本:检索带有转义序列的变量的值时,转义序列字符的行为如何?

时间:2018-09-12 05:04:52

标签: bash shell escaping

我有test.sh,如下所示。当我从bash shell中像./test.sh一样运行它时,我得到的输出如下所示。

test.sh

operator="\*"
echo $operator
expr 5 $operator 1
expr 5 \* 2

输出

\*
expr: syntax error
10

我不明白为什么在第四条语句按预期方式工作时,第三条语句为什么会出现语法错误。 如果expr仅将*作为第三条语句中的第二个参数,那么回显输出\ *是什么?

1 个答案:

答案 0 :(得分:1)

bash中shell扩展的最后阶段是quote removal

  

在前面的扩展之后,所有未加引号的   字符“ \,“ '”和“ "”不是由   以上扩展已删除。

这里的“以上扩展”是参数(变量)扩展,命令替换等。

expr 5 \* 2中,\将被bash作为引号删除的一部分删除,因为它不是变量(或其他)扩展的结果。所以在这里,expr得到的参数是*,在删除\之后。

expr 5 $operator 1echo $operator中,\ 不会被删除,因为它是变量扩展的结果。因此,在这两个命令中,echoexpr得到的参数是\*,而没有删除\


最好的方法是始终使用引号:

operator="*"

echo "$operator"
expr 5 "$operator" 2

否则,如果\*碰巧被设置为一个奇怪的值,则IFS仍可能会进行字段拆分:

bash-4.4$ foo='\*'
bash-4.4$ echo $foo
\*
bash-4.4$ IFS='*'
bash-4.4$ echo $foo
\
bash-4.4$ echo "$foo"
\*