Bash 难以理解反斜杠在反斜杠内部的不明显用法

Bash 难以理解反斜杠在反斜杠内部的不明显用法,bash,backslash,Bash,Backslash,我已经阅读了包括bash手册在内的大量页面,但仍然发现反斜杠的“不明显”用法令人困惑 如果我这样做: echo \* echo \\* 它只打印一个星号,这是很正常的,因为我将星号转义为文字 如果我这样做: echo \* echo \\* 它打印\* 这似乎也很正常,第一个反斜杠逃避了第二个反斜杠 如果我这样做 echo `echo \\*` 它打印目录的内容。但在我看来,它应该和echo\\*一样打印,因为当它被替换并传递给echo时。我知道大家都在谈论反斜杠,但我很难理解为什么会

我已经阅读了包括bash手册在内的大量页面,但仍然发现反斜杠的“不明显”用法令人困惑

如果我这样做:

echo \*
echo \\*
它只打印一个星号,这是很正常的,因为我将星号转义为文字

如果我这样做:

echo \*
echo \\*
它打印
\*
这似乎也很正常,第一个反斜杠逃避了第二个反斜杠

如果我这样做

echo `echo \\*`
它打印目录的内容。但在我看来,它应该和echo\\*一样打印,因为当它被替换并传递给echo时。我知道大家都在谈论反斜杠,但我很难理解为什么会发生这种情况

bash手册还说

当使用旧式反引号形式的替换时,反斜杠保留其字面含义,除非后跟“$”、“`”或“\”

但它没有定义什么是“反斜杠上的字面意思”。它是一个转义字符,一个延续字符,还是一个反斜杠字符


而且,它说它保留了它的字面意思,除非后面跟。。。那么,当它后面跟着这三个字符中的一个时,它会做什么呢?它是否仅转义了这三个字符

这主要是出于历史原因,因为
`…`
命令替换已被更干净的
$(…)
表单取代。任何新脚本都不应使用反勾号

下面是如何评估
$(命令)
替换

  • 运行命令
  • 下面是如何评估
    `string`
    命令替换:

  • 确定字符串的范围,从开始的回勾号到结束的未转义回勾号(如果此回勾号位于字符串文本内,则行为未定义:shell通常将其视为文本回勾号或结束回勾号,具体取决于其解析器实现)
  • 通过删除美元、反勾号或反斜杠三个字符之一之前的反斜杠来取消字符串的换行。然后将以下字符按字面意思插入命令中。后面跟有任何其他字符的反斜杠将被保留。
    • 例如,
      Hello\\World
      将变为
      Hello\World
      ,因为
      \
      替换为
      \
    • Hello\World
      也将变成
      Hello\World
      ,因为反斜杠后面跟的不是这三个字符中的一个,因此保留了反斜杠的字面含义
    • \\*
      将变为
      \*
      ,因为
      \\
      将变为
      \
      (因为反斜杠是三者之一),而
      \*
      将保持
      \*
      (因为星号不是)
  • 将结果作为shell命令进行求值(这包括对现在未转义的命令字符串的结果遵循所有常规shell转义规则)
  • 因此,要计算echo`echo\\*`:

  • 确定字符串的跨度,此处
    echo\\\*
  • 根据倒勾引用规则取消对其进行替换:
    echo\*
  • 将其作为命令进行评估,该命令运行echo以输出文本
    *
  • 由于替换结果不带引号,因此输出将经历:
  • 分词:
    *
    变成
    *
    (因为它只是一个词)
  • 每个单词上的路径名扩展,因此
    *
    变成
    bin
    桌面
    根据当前目录中的文件下载
    照片
    公共html
  • 请特别注意,这与用输出替换backtick命令并重新运行结果不同。例如,我们没有考虑输出中的逸出、引文和扩展,这是一个基于文本的宏扩展。
  • 将这些参数作为参数传递给下一个命令(也是echo):
    echo bin Desktop Downloads Photos public\u html

  • 结果是当前目录中的文件列表。

    “字面意义”表示它实际上是字符串中的ASCII码点92,而不是有向图的一部分。请注意,
    echo\\\*
    echo$(echo\\\\*)
    打印的内容相同,并且
    $()
    通常是在子shell中调用命令的首选方法…这就是为什么我们喜欢
    $()
    而不是反斜杠。因此,当使用旧式的反引号替换形式时,手册可以阅读(为了简化),反斜杠是字面反斜杠,除非后面跟一个美元符号、反引号或另一个反斜杠,在哪种情况下,它会被移除?这是一个准确的陈述吗?@Vonedaddy它是准确的,尽管不完整。例如,它没有明确地说
    \\\\\
    应该变成
    \\
    ,即使3个反斜杠后面跟着另一个反斜杠,虽然它说
    \`
    应该变成
    `
    ,但它没有明确地说不应该终止替换。明白。但手册的第二行将涵盖反向报价终止。它声明第一个不带反斜杠的反引号终止命令替换。非常感谢你的崩溃。它确实帮助我了解了它的工作原理。非常感谢你。