bash 的词法分析器使用什么分隔符将命令分解为单词?

bash 的词法分析器使用什么分隔符将命令分解为单词?

来自 bash 手册,关于波形符扩展:

如果一个字以不带引号的波浪号字符 ('~') 开头,直到第一个不带引号的斜杠之前的所有字符(或所有字符,如果没有不带引号的斜杠)都被视为波浪号前缀 。

我想知道为什么~被识别为波形符前缀

$ mypath=/program_files:~/home/t
$ echo $mypath
/program_files:/home/t/home/t

mypath=/program_files:~/home/tbash 的词法分析器将哪些单词拆分成什么?是否被~/home/t准确地识别为单词?

bash 的词法分析器使用什么单词分隔符将命令分解为单词?:和 是= 单词分隔符吗?它们也是文字吗?

谢谢。

这源于我无法理解https://unix.stackexchange.com/a/448469/674

无法理解 PATH 字符串内的波形符。这就是为什么 POSIX 标准要求在分配 shell 宏时在命令行中的冒号后面扩展波形符序列。

答案1

这不是单词分割的结果(更准确地说,是标记分割),而是波形符扩展在变量赋值中:

每个变量赋值都会检查紧跟在“:”或第一个“=”之后的未加引号的波形符前缀。在这些情况下,还会执行波形符扩展。

当 bash 将命令分割成标记时,bash 使用的单词分隔符是它的元字符:

不加引号时用于分隔单词的字符。元字符可以是空格、制表符、换行符或以下字符之一:“|”、“&”、“;”、“(”、“)”、“<”或“>”。

mypath=/program_files:~/home/t

从 bash 的角度来看,它是一个单一的标记。

答案2

波浪号在赋值中扩展为,PATH因为它是一个变量赋值,并且波浪号紧接在未加引号的冒号之后(在您的示例中)。

“波形符前缀”由<tilde>单词开头的未加引号的字符组成,后跟<slash>单词中第一个未加引号之前的所有字符,或者如果没有 则为单词中的所有字符<slash>。在赋值中(请参阅 XBD 变量赋值),可以使用多个波形符前缀:在单词的开头(即,在<equals-sign>赋值的后面),在任何未引用的<colon>, 或两者。

(从关于波形符扩展的 POSIX 文本

手册bash是这样说的

每个变量赋值都会检查紧跟在 a:或第一个后面的未加引号的波形符前缀=。在这些情况下,还会执行波形符扩展。因此,可以在对 、 和 的赋值中使用带波形符的文件名PATHMAILPATH并且CDPATHshell 会分配扩展值。

这意味着将不带引号的字符串分配/program_files:~/home/tPATH将扩展其中的波形符,并且这$PATH将是扩展了波形符的字符串。

在 中放置文字波浪号PATH(例如通过引用字符串)将导致该目录的命令路径名解析失败(除非当前工作目录中存在具有该文字名称的目录)。

bashPATH当不在 POSIX 模式下时,在查找命令时仍会扩展这些波形符。


当 shell 扫描该行时

mypath=/program_files:~/home/t

它作为单个标记返回到解析器。它将作为一个简单的命令进行处理。

一个简单的命令,当被识别为一个赋值时,会经历波浪线扩展等。在 的右侧进行波形符扩展时=,shell 会将字符串中的波形符扩展至当前用户的主目录,因为它出现在冒号之后。

也可以看看简单命令的 POSIX 文本

相关内容