提问人:mishar 提问时间:2/10/2020 更新时间:2/10/2020 访问量:812
bash 变量替换和引用
bash variable substitution and quoting
问:
也许这是一个简单的问题,但我想知道引号如何使用变量。变量值周围的引号是否也会被替换为该变量? 例如:
fred="\*"
echo $fred
结果为输出:
\*
为什么?我认为这会被替换为$fred,因此输出将是:\*
*
但事实并非如此。
答:
man bash
“引用”部分(我的重点):
将字符括在双引号中可保留引号内所有字符的文本值,但 $、'、\ 和 (启用历史记录扩展时) !。当 shell 处于 posix 模式时,!在双引号中没有特殊含义,即使启用了历史记录扩展也是如此。字符 $ 和 ' 在双引号内保留了其特殊含义。只有当后面跟着以下字符之一时,反斜杠才保留其特殊含义:$、'、“、\ 或 <换行符>。
因此,与其他一些语言不同,反斜杠不会转义每个字符。
评论
来自 bash 手册 Shell 扩展强调我的:
扩展的顺序为:大括号扩展;波浪号扩展、参数和变量扩展、算术扩展和命令替换(以从左到右的方式完成);拆词;和文件名扩展。
在可以支持它的系统上,还有一个额外的扩展可用:流程替代。这与波浪号、参数、变量、算术扩展和命令替换同时执行。
执行这些扩展后,将删除原始单词中存在的引号字符,除非它们本身已被引用(引号删除)。
那么引号删除扩展是可以替代的东西,强调我的:\*
*
在前面的扩展之后,将删除所有不是由上述扩展之一产生的字符 '\'、''' 和 ''' 的未加引号的出现。
然而,这里发生了一个扩展(具有重要意义)——变量扩展。 被替换为变量扩展。该字符串是另一个扩展的结果,因此不会对其执行引号删除。所以它保持为 .$fred
\*
\*
\*
变量值周围的引号是否也会被替换为该变量?
不。 包含两个字符。$fred
\*
为什么?
如果它是由另一个扩展引起的,则不会删除。\
您可能对文件名扩展感兴趣。当单词拆分扩展后的“单词”对于文件名扩展“合格”时,就会发生文件名扩展。“word”限定用于文件名扩展,例如,如果存在不在单引号或双引号内且未转义的字符。in 是用反斜杠字符转义的,所以这里不是“图案字符”......在结果中,不执行文件名扩展。*
*
\*
*
通配是否真的发生在分配时?
不。“Globing”即。变量赋值时不执行文件名扩展。从 bash shell 参数:
变量可以通过以下形式的语句赋值
name=[value]
...不执行文件名扩展。...
有趣的是:您可以使用 3 个斜杠触发文件名扩展:
fred="\\\*"
touch '\file_with_backslash'
echo $fred # will output `\file_with_backslash`
# and other files you have with leading backslash...
所以 assings to (two 代替 single )。然后在 中,因为反斜杠是转义的斜杠,所以左边没有转义,所以它是一个模式字符,并且该单词符合文件名扩展的条件。fred="\\\*"
\\*
fred
\\
\
echo $fred
\\
*
评论