简体   繁体   English

为什么 bash 的行注释技巧不适用于感叹号“!”

[英]Why does line comment tricks for bash not work with exclamation mark "!"

ref Inline comments for Bash?参考Bash 的内联注释?

We can use this tricks我们可以使用这个技巧

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

but these do not work if we have an exclamation mark in comment但是如果我们在评论中有感叹号,这些就不起作用

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

if we type it directly it will not be translated to an event如果我们直接输入它,它不会被翻译成一个事件

# 2 !3
<that is OK>

It seams that we need an other # symbol to workaround it.看来我们需要另一个#符号来解决它。

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

or do we have to double the leading # symbol?还是我们必须将前导#符号加倍?

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

(The following explanation turned out to be WRONG though it explained everything. See the UPDATE as follows.) (以下解释虽然解释了一切,但结果证明是错误的。请参阅以下更新。)

  1. # !xxx

This works as expected because !这按预期工作,因为! is in the comment.在评论中。

  1. echo # !xxx

This also works as expected because !这也按预期工作,因为! is also in the comment.也在评论里。

  1. echo `true # !xxx`

This also works because !这也有效,因为! is still in the comment, though it's in the `...` context.仍在评论中,尽管它在`...`上下文中。

  1. echo `# !xxx`

Why doesn't this work?为什么这不起作用?
I guess there's a little bug when Bash interprets the `...` part.我猜当 Bash 解释`...`部分时会有一个小错误 In `...` , Bash always assumes (wrongly) the first WORD is a COMMAND name so it does not think !`...` ,Bash 总是(错误地)假设第一个WORD 是一个 COMMAND 名称,所以它不认为! is in a comment and so history expansion is triggered.在评论中,因此触发历史扩展。 That's to say, echo `# !xxx` is just like echo `COMMAND !xxx` .也就是说, echo `# !xxx`就像echo `COMMAND !xxx`

  1. echo `# # !xxx`

Why does this work?为什么这样做?
As explained in #4 , the first # is parsed as a COMMAND so it's just like echo `COMMAND # !xxx` so now !正如#4 中所解释的,第一个#被解析为命令,所以它就像echo `COMMAND # !xxx`所以现在! is in the comment.在评论中。

  1. echo `## !xxx`

This double hash does not work either.这个双散列也不起作用。
As explained in #4 and #5 , here ## is the first WORD and it's parsed as the COMMAND name so it's also like echo `COMMAND !xxx` .正如#4#5 中所解释的,这里##是第一个 WORD,它被解析为 COMMAND 名称,因此它也类似于echo `COMMAND !xxx`

Note that, in the `...` context, the bug is only in the first round syntax parser .请注意,在`...`上下文中,错误仅出现在第一轮语法解析器中 That's to say, even though Bash initially parses the # as a COMMAND name, it does not really run it as a command which is named # .也就是说,即使 Bash 最初将#解析为 COMMAND 名称,它并没有真正将其作为名为#的命令运行。


UPDATE 2020-03-04更新 2020-03-04

The above explanation turned out to be WRONG though it explained everything.上面的解释虽然解释了一切,但结果证明是错误的 Please see the discussion in bug-bash mailing list .请参阅bug-bash 邮件列表中的讨论

I'd quote Chet's explanation here for easy reference:我在这里引用 Chet 的解释以供参考:

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

Well, the history comment character ( # ) is not found at the start of a word (here # is part of the word `# ) , so the rest of the line is processed for history expansion.好吧,在单词的开头找不到历史注释字符 ( # ) (这里#单词`# ,因此该行的其余部分被处理以进行历史扩展。

 $ true `# # !xxx`

The history comment character is found at the start of a word (here the 2nd # itself is a word ) and history expansion skips the rest of the line.历史注释字符位于单词的开头(这里第二个#本身是一个单词并且历史扩展跳过该行的其余部分。

Readline history expansion knows very little about shell syntax; Readline 历史扩展对 shell 语法知之甚少; in particular, it doesn't know backquotes.特别是,它不知道反引号。 It never has.它从来没有。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM