bash 中的历史扩展何时发生?

bash 中的历史扩展何时发生?

历史扩展什么时候发生?

  1. 来自 bash 手册

    将字符括在双引号 ('"') 中会保留引号内所有字符的字面值,但 '$'、'`'、'\' 和启用历史扩展时的 '!' 除外。

    由于解析器在解析阶段识别双引号,因此解析后必须进行历史扩展是否正确?

    如果是,那么 shell 扩展(例如大括号扩展、参数扩展、文件名扩展等)何时发生?

  2. 但我认为历史扩展是由shell的readline提供的,所以是在词法分析和解析之前处理的?就像 shell 中的自动完成一样。我错过了什么吗?

谢谢。

答案1

引用bash 手册:

读取完整行后,在 shell 将其分解为单词之前,立即执行历史扩展。

历史扩展是处理的第一阶段,甚至在 shell 解析之前,这就是双引号的原因protected !:后者在双引号之前处理。它由历史库处理,历史库实现自己的解析,并有几种保护历史运算符的方法:

只有 ' \' 和 ' '' 可以用于转义历史扩展字符,但如果历史扩展字符紧接在双引号字符串中的结束双引号之前,则也将其视为带引号的。

当 shell 的解析器开始处理字符串时,它已经被历史库解析并且历史扩展已经发生。

答案2

正如@Stephen Kitt所说,历史扩展应该在第一阶段完成。这种模式可以通过以下事情来理解:如果我们输入任意 bash 代码,例如

echo "the value of a is $a" > tmp

然后我们使用use历史扩展,

!-1

很明显,上面的行会再次执行相同的操作。我们应该注意到的是,它将!-1扩展到echo "the value of a is $a" > tmp第一个。如果这种扩展发生在解析阶段之后,那么我们应该意识到$a将无法正确解析,但实际上并没有发生。

相关内容