在 Bash 中创建多行注释的方法?

Way to create multiline comments in Bash?

我最近开始研究 shell 脚本,我希望能够注释掉 shell 脚本中的一组行。我的意思是就像 C/Java 的情况一样:

/* comment1
   comment2 
   comment3
*/`

我该怎么做?

使用: '打开,'关闭。

例如:

: '
This is a
very neat comment
in bash
'

bash

中的多行注释
: <<'END_COMMENT'
This is a heredoc (<<) redirected to a NOP command (:).
The single quotes around END_COMMENT are important,
because it disables variable resolving and command resolving
within these lines.  Without the single-quotes around END_COMMENT,
the following two $() `` commands would get executed:
$(gibberish command)
`rm -fr mydir`
comment1
comment2 
comment3
END_COMMENT

注意:我根据评论和其他答案更新了此答案,因此 2020 年 5 月 22 日之前的评论可能不再适用。我今天还注意到一些 IDE 像 VS Code 和 PyCharm 不识别包含空格的 HEREDOC 标记,而 bash 没有问题,所以我正在更新这个再次回答。

Bash 不提供用于多行注释的内置语法,但有一些黑客使用现有的 bash 语法“恰好现在可以工作”。

我个人认为最简单的(即最少噪音、最不奇怪、最容易输入、最明确)是使用带引号的 HEREDOC,但要明确你在做什么,并在所有地方使用相同的 HEREDOC 标记:

<<'###BLOCK-COMMENT'
line 1
line 2

line 3
line 4
###BLOCK-COMMENT

单引号 HEREDOC 标记避免了一些 shell 解析副作用,例如会导致崩溃或输出的奇怪替换,甚至是标记本身的解析。所以单引号让你在打开-关闭评论标记上有更多的自由。

例如,以下使用三重散列,在 bash 中建议多行注释。如果没有单引号,这会使脚本崩溃。即使您删除了 ###,如果没有单引号,FOO{} 也会使脚本崩溃(或者如果没有 set -e 则导致错误的替换被打印出来):

set -e

<<'###BLOCK-COMMENT'
something something ${FOO{}} something
more comment
###BLOCK-COMMENT

ls

你当然可以只使用

set -e

<<'###'
something something ${FOO{}} something
more comment
###

ls

但是对于不熟悉这种诡计的 reader 来说,这样做的意图肯定不太清楚。

请注意我原来的答案使用 '### BLOCK COMMENT',如果你使用 vanilla vi/vim 就没问题,但今天我注意到 PyCharm 和 VS Code 无法识别结束标记有空格。

如今,任何优秀的编辑器都允许您按 ctrl-/ 或类似的方式来 un/comment 选择。这个大家肯定都明白:

# something something ${FOO{}} something
# more comment
# yet another line of comment

尽管不可否认,如果您想重新填写段落,这远不如上面的块注释方便。

当然还有其他技术,但似乎没有一种“常规”方法可以做到这一点。如果 ###>###< 可以添加到 bash 以指示评论块的开始和结束,那就太好了,看起来它可能非常简单。

在阅读了此处的其他答案后,我想出了以下内容,恕我直言,它非常清楚这是一条评论。特别适合脚本内使用信息:

<< ////

Usage:
This script launches a spaceship to the moon. It's doing so by 
leveraging the power of the Fifth Element, AKA Leeloo.
Will only work if you're Bruce Willis or a relative of Milla Jovovich.

////

作为一名程序员,斜线序列立即在我的大脑中注册为注释(尽管斜线通常用于行注释)。

当然,"////"只是一个字符串;前缀和后缀中的斜杠数量必须相等。

你对此有何看法?

function giveitauniquename()
{
  so this is a comment
  echo "there's no need to further escape apostrophes/etc if you are commenting your code this way"
  the drawback is it will be stored in memory as a function as long as your script runs unless you explicitly unset it
  only valid-ish bash allowed inside for instance these would not work without the "pound" signs:
  1, for #((
  2, this #wouldn't work either
  function giveitadifferentuniquename()
  {
    echo nestable
  }
}

下面是我如何在 bash 中进行多行注释。

这个机制有两个我很欣赏的优点。一是注释可以嵌套。另一个是可以通过简单地注释掉启动行来启用块。

#!/bin/bash
# : <<'####.block.A'
echo "foo {" 1>&2
fn data1
echo "foo }" 1>&2
: <<'####.block.B'
fn data2 || exit
exit 1
####.block.B
echo "can't happen" 1>&2
####.block.A

在上面的示例中,"B" 块被注释掉了,但是 "A" 块中不是 "B" 块的部分没有被注释掉。

运行 该示例将产生以下输出:

foo {
./example: line 5: fn: command not found
foo }
can't happen

简单的解决方案,不太聪明:

暂时阻止脚本的一部分:

if false; then
    while you respect syntax a bit, please
    do write here (almost) whatever you want.
    but when you are
    done # write
fi

有点复杂的版本:

time_of_debug=false # Let's set this variable at the beginning of a script

if $time_of_debug; then # in a middle of the script  
    echo I keep this code aside until there is the time of debug!
fi

我尝试了选择的答案,但发现当我 运行 一个包含它的 shell 脚本时,整个事情都被打印到屏幕上(类似于 jupyter notebooks 在 '''xx''' 引号),最后有一条错误消息。它什么也没做,但是:吓人。然后我在编辑它时意识到单引号可以跨越多行。所以..让我们把块分配给一个变量。

x='
echo "these lines will all become comments."
echo "just make sure you don_t use single-quotes!"

ls -l
date

'

简而言之bash 注释掉 一段代码 我愿意

:||{ 堵塞 代码 }