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

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

/* comment1
comment2
comment3
*/`

我怎么能那样做呢?

324658 次浏览

使用: '打开,'关闭。

例如:

: '
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

但对于不熟悉这种花招的读者来说,这样做的目的肯定不太清楚。

请注意,我最初的答案使用'### BLOCK COMMENT',如果你使用香草vi/vim,这是很好的,但今天我注意到,PyCharm和VS Code不识别关闭标记,如果它有空格。

现在,任何好的编辑器都允许你按ctrl-/或类似的键来取消/注释所选内容。每个人都明白这一点:

# 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笔记本如何打印出'''xx'''引号中的所有内容),并且在结束时有一个错误消息。它没有做任何事情,但是:可怕的。后来我在编辑的时候意识到单引号可以跨越多行。所以. .让我们把这个块赋值给一个变量。

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


ls -l
date


'

在普通bash 注释掉 一段代码 我做< / p > < p >: | | { 块 的代码 } < / p >