我有test.sh,如下所示。当我从bash shell中像./test.sh一样运行它时,我得到的输出如下所示。
test.sh
operator="\*"
echo $operator
expr 5 $operator 1
expr 5 \* 2
输出
\*
expr: syntax error
10
我不明白为什么在第四条语句按预期方式工作时,第三条语句为什么会出现语法错误。 如果expr仅将*作为第三条语句中的第二个参数,那么回显输出\ *是什么?
答案 0 :(得分:1)
bash中shell扩展的最后阶段是quote removal:
在前面的扩展之后,所有未加引号的 字符“
\
,“'
”和“"
”不是由 以上扩展已删除。
这里的“以上扩展”是参数(变量)扩展,命令替换等。
在expr 5 \* 2
中,\
将被bash作为引号删除的一部分删除,因为它不是变量(或其他)扩展的结果。所以在这里,expr
得到的参数是*
,在删除\
之后。
在expr 5 $operator 1
和echo $operator
中,\
不会被删除,因为它是变量扩展的结果。因此,在这两个命令中,echo
和expr
得到的参数是\*
,而没有删除\
。
最好的方法是始终使用引号:
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"
\*