未加引号的元字符如何成为标记的一部分?

未加引号的元字符如何成为标记的一部分?

在阅读了@Tim 关于 shell 语法的一些问题后,我正在浏览bash手册页,然后我提出了我自己的一个(简单的)问题。

以下是摘录man bash(请自行查看LESS=+/^DEFINITIONS man bash

   word   A  sequence  of  characters  considered  as a single unit by the
          shell.  Also known as a token.
   ...
   metacharacter
          A character that, when unquoted, separates words.   One  of  the
          following:
          |  & ; ( ) < > space tab
   control operator
          A token that performs a control function.  It is one of the fol-
          lowing symbols:
          || & && ; ;; ( ) | <newline>

但这是我没有得到的圆圈:

  • ;是一个“元字符”。
  • “元字符”在不加引号时分隔“单词”。
  • “令牌”是我们可以用来表示“单词”的另一个术语。
  • ;;是一个令牌。
  • 因此;;是一个词。

但是,这意味着它是一个由两个单词分隔符组成的单词。鉴于它没有被引用,并且不需要它周围的空白来识别(或者是吗??),这怎么可能?


如果您好奇,我正在阅读的有关 shell 语法的其他问题如下:

答案1

Bash 使用与 POSIX 相同的术语(毫不奇怪)。使用它进行比较(偶尔进行澄清)。

引用自定义

3.113 控制操作员

在 shell 命令语言中,执行控制功能的标记。它是以下符号之一:

&   &&   (   )   ;   ;;   newline   |   ||

shell 内部使用的输入结束指示器也被视为控制运算符。

注:Token Recognition在XCU中有详细定义令牌识别

3.407 代币

在 shell 命令语言中,shell 认为的字符序列单个单元读取输入时。标记可以是运算符或单词。

注:读取输入的规则在XCU中有详细定义令牌识别

3.440 单词

在 shell 命令语言中,除运算符之外的标记。在某些情况下,单词也是单词标记的一部分:在各种形式的参数扩展(例如 ${name-word})和变量赋值(例如 name=word)中,单词是所描述的标记的一部分通过言语。在单词扩展之后,单词的概念不再适用,仅保留字段。

注:更多信息,请参见 XCU参数扩展词表达式

所以你看,“单词”和“令牌”之间有区别,并且它们不是问题中暗示的同义词。而且,该标准并不认为两个分号是单独的字符,而是一个单个单元

答案2

bash解析词法分析器生成的标记。当bash把行分成单词时,很可能是使用字符。当它解析命令语法时,它使用标记。在这种情况下,;;不是两个“;”字符,更确切地说,它是由两个“;”组成的令牌。 (分号)字符。 bash 的词法分析器以允许将字符组识别为标记的方式读取传入的字符流。因此,代码实际上看不到分号,而是看到令牌代码。

请参阅flexbison工具来了解这一点。我不相信 bash 使用这些,但它们是用于类似解析应用程序的工具,并且有关于解析通常如何完成的概述材料。

GNU Bash 参考手册是一个值得阅读的好文档。写得很好,但比手册页更具解释性。

答案3

是的,;;是一个词。但它不是两个元字符在一起。
这是案例陈述的结尾:

case a in 
    [a-z]) echo "yes" ;;
esac

或者单行:

case a in [a-z]) echo "yes" ;; esac

是的,它与“是”之间用一个空格隔开,所以它是一个单词。
但不一定是这样:

case a in [a-z]) echo "yes";; esac

是的,非常具体的问题的措辞有时可能会令人困惑。

相关内容