【问题标题】:Why does line comment tricks for bash not work with exclamation mark "!"为什么 bash 的行注释技巧不适用于感叹号“!”
【发布时间】:2020-05-26 16:38:25
【问题描述】:

参考Inline comments for Bash?

我们可以使用这个技巧

echo abc `#put your comment here` \
     def `#another chance for a comment` \
     xyz etc

但如果我们在评论中有感叹号,这些都不起作用

echo 1 `# 2 !3`
<error>
-bash: !3: event not found

如果我们直接输入它不会被翻译成事件

# 2 !3
<that is OK>

我们需要另一个 # 符号来解决它。

echo 1 `# 2 #!3`
<that is OK>
1

还是我们必须将前导 # 符号加倍?

echo 1 `# # 2 !3`
<that is OK>
1

【问题讨论】:

  • 它不是特定于 cmets,您在其他代码段中也会遇到同样的问题。您需要单引号引用您的评论,或使用 set +H 禁用历史扩展
  • @Aaron 这似乎是一个不同的问题
  • 是的,因为问题的 OP 使用了一种现在可以使用但在 bash
  • @Aaron 引用不起作用,但我发现双前导哈希可以解决方法

标签: bash


【解决方案1】:

(以下解释结果是错误,尽管它解释了一切。请参阅UPDATE如下。)

  1. # !xxx

这按预期工作,因为! 在评论中。

  1. echo # !xxx

这也可以正常工作,因为! 也在评论中。

  1. echo `true # !xxx`

这也有效,因为 ! 仍在评论中,尽管它在 `...` 上下文中。

  1. echo `# !xxx`

为什么这不起作用?
我猜当 Bash 解释 `...` 部分时会有一点 错误。在`...` 中,Bash 总是(错误地)假设 first WORD 是一个 COMMAND 名称,因此它认为! 不在评论中,因此触发了历史扩展。也就是说echo `# !xxx`就像echo `COMMAND !xxx`一样。

  1. echo `# # !xxx`

为什么会这样?
#4 中所述,第一个 # 被解析为 COMMAND,所以它就像 echo `COMMAND # !xxx` 所以现在 ! 在评论中。

  1. echo `## !xxx`

这种双重哈希也不起作用。
#4#5 中所述,这里 ## 是第一个 WORD,它被解析为 COMMAND 名称,因此它也类似于 echo `COMMAND !xxx`

请注意,在`...` 上下文中,bug 仅存在于第一轮语法parser 中。也就是说,尽管 Bash 最初将 # 解析为 COMMAND 名称,但它并没有真正将其作为名为 # 的命令运行。


2020-03-04 更新

上面的解释结果是错误,尽管它解释了一切。请参阅the discussion in bug-bash mailing list

为了方便参考,我在这里引用 Chet 的解释:

> $ set -H
> $ true `# !xxx`
> bash: !xxx`: event not found

嗯,历史注释字符 (#) 在开头找不到 word (这里#word `#的一部分),所以该行的其余部分被处理以进行历史扩展。

$ true `# # !xxx`

历史注释字符位于单词的开头(这里第二个#本身就是一个单词和历史 扩展跳过该行的其余部分。

Readline 历史扩展对 shell 语法知之甚少;在 特别是,它不知道反引号。从来没有。

【讨论】:

    猜你喜欢
    • 2020-08-16
    • 1970-01-01
    • 2013-04-25
    • 2017-06-11
    • 1970-01-01
    • 2011-12-22
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多