我在 bash 备份脚本中遇到了一个问题,它是由以下我不理解的行为引起的。
首先,我们创建一个参数,其中包含一个包含 2 个连续空格的字符串(位于 '<' 之前):
me@mysystem:~$ TEST="a string with 2 spaces right <--HERE!"
me@mysystem:~$ echo $TEST
a string with 2 spaces right <--HERE!
我可以 grep 一个空格:
me@mysystem:~$ echo ${TEST} | grep " "
a string with 2 spaces right <--HERE!
我可以 grep 一个空格后面跟着另一个字母:
me@mysystem:~$ echo ${TEST} | grep " s"
a string with 2 spaces right <--HERE!
我可以 grep 两个空格后面的部分:
me@mysystem:~$ echo ${TEST} | grep "HERE"
a string with 2 spaces right <--HERE!
我可以进行变量扩展,用下划线替换两个空格:
me@mysystem:~$ echo ${TEST// /_}
a_string_with_2_spaces_right__<--HERE!
但是 grepping 双倍空格需要引用变量:
me@mysystem:~$ echo $TEST | grep " "; echo "Done."
Done.
me@mysystem:~$ echo ${TEST} | grep " "; echo "Done."
Done.
me@mysystem:~$ echo "$TEST" | grep " "; echo "Done."
a string with 2 spaces right <--HERE!
Done.
me@mysystem:~$ echo "${TEST}" | grep " "; echo "Done."
a string with 2 spaces right <--HERE!
Done.
我不明白为什么会这样。
长话短说:我在脚本中有一个 if 语句,用于检查 ${FILE} 是否代表现有文件,并且当遇到空格(除非加引号)时,该语句显然也会停止解释变量。因此,我不再确定 ${} 实际上会做什么或不会做什么。
我猜最好总是引用变量?
答案1
这是 shell 对未引用的变量扩展进行单词拆分的经典案例。
基本上当你这样做时$TEST
(不带引号("$TEST"
)),shell:
根据
IFS
环境变量的值(默认值:空格、制表符、换行符)执行单词拆分,并将整个扩展拆分为单独的单词因此,由于您有两个连续的空格,因此单词拆分(以及路径名(glob)扩展(如果存在
*
、?
、中的任何一个)已完成,并且当重建输出字符串时,单词由空格连接,因此您在和[]
之间只有一个空格。对于任何字符组合都是如此。right
<--HERE!
IFS
简而言之,引用你的变量扩展:
"${variable}"