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


224

我最近开始研究Shell脚本,并且希望能够注释掉Shell脚本中的几行内容。我的意思是在C / Java的情况下:

/* comment1
   comment2 
   comment3
*/`

我该怎么办?


2
您可以像这样使用哈希:#这是一条注释。
Mohammad Tayyab'4

1
我知道,但是对于多行来说有点麻烦。
Enes Malik Turhan

2
应该注意的是,下面的答案要求:在行的第一列(没有前导空格)中。
ty

Answers:


392

使用: '在打开和'关闭。

例如:

: '
This is a
very neat comment
in bash
'

27
:(而且还增加了未读能力和潜力的bug源大量恕我直言,是更好的只是使用多个。#S和从来没有这个...
jm666

51
@ jm666恕我直言,当您不了解所有用例时,永远不要使用永不这个词。

19
解释::是简写形式,truetrue不会处理任何参数。(手册页:SYNOPSIS true [ignored command line arguments]
phil294 '17

46
:和之间的间隔'很重要
Becko

23
我对代码块做了些微修改,以便可以轻松地打开或关闭代码。我的更改是# '在最后一行而不是单引号上使用。这样,我可以#在第一行放置一个来激活代码块。删除#第一行上的以停用代码。
JohnMudd

131

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

4
此方法有效,当前接受的答案不(对我而言)。
Freek

5
可能值得注意的是,这本身不是评论。这是一个多行字符串重定向到NOP命令的Heredoc。单引号对于禁用解析变量和命令很重要。
Nux

1
@Freek需要增加空间
令人惊叹

我在一个简单的bash脚本中进行了测试,该脚本通过shebang行在Debian中运行#!/ bin / bash而失败了。我正在尝试此页面上的每个答案,但都失败了,直到我到达下面的答案为止。由于它们失败了,所以我对它们进行否决,而对实际运行正常的问题进行表决。
PyTis

1
您的示例中的良好测试。领导:是没有必要的。刚开始<<
wisbucky

34

我将根据评论和其他答案更新此帖子,因此2020年5月22日之前的评论可能不再适用。

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

但是对于不熟悉此技巧的读者,其意图肯定不够清楚。

如今,任何优秀的编辑器都允许您按ctrl- /或类似内容来取消/注释选择。每个人都绝对理解:

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

尽管可以接受,但是如果您想重新填写段落,这不如上面的块注释方便。

当然还有其他技术,但是似乎没有“常规”的方法可以做到。如果###>并且###<可以将其添加到bash中以指示注释块的开始和结束,那将是一件很不错的事情,似乎很简单。


1
啊,这个简单/干净,足以记住!
Thamme Gowda

1
如前面的答案所述,除了反引号外,$(...)序列也将被扩展,因为两种形式都是命令替换。
Perl Ancar,

“两者都是黑客,因此它们将来可能会破坏脚本。” 您能对此进行扩展吗?尽管从语义上讲骇客,但从语法上讲,它们是有效的,将来不应破解,除非bash决定发疯并破坏heredocs。
Perl Ancar,

@perlancar如果我们同意黑客是使用与问题完全无关的语言/库功能的解决方案(例如使用Heredoc进行注释,或在诸如do-nothing命令上使用参数true),即使它们没有不要冒险破坏(heredoc方法没有,但冒号版本可以),1)黑客仍然掩盖了意图:如果没有第一行暗示多行注释,大多数人会想知道代码在做什么;和2)有意外的暗角(例如必须加双引号,在某些情况下用heredoc标记加引号等)。
奥利弗

@Oliver:如果不加引号,变量可能会带来讨厌的副作用。想象一下,您已经在heredoc中嵌入了一个注释,例如,字符串${FOO:=bar}or ${FOO{}}。第一个可能对创建和设置变量有副作用FOO,第二个将引发严重的替换 错误;这两种效果您都不希望从真实评论中获得。
user1934428

24

在阅读了其他答案之后,我想到了以下内容,恕我直言,这很明显是一则评论。特别适用于脚本使用信息:

<< ////

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.

////

作为程序员,斜线序列会立即在我的大脑中记录为注释(即使斜线通常用于行注释)。

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


3
我差点错过了Usage:
RNA

除了以上答案外,其他功能也很棒。老实说,我认为您可以编辑以上答案,并将其添加到其中,而不用单独回答。
PyTis

有几个“以上”答案(取决于您的排序顺序)。而且,通过单独回答,我想解释我选择的字符串背后的原理。
noamtm

<< EOF ... EOF
l mingzhi

5

您对此有何看法?

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
  }
}

你好,不是要问问题,而不是要回答原始问题
Imre

不好的IMO。它要求注释可解析为shell代码,这是非常严格的。
user1934428

3

这是我在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

3

我尝试了选择的答案,但是发现当我运行包含它的shell脚本时,整个东西都被打印到屏幕上了(类似于jupyter笔记本如何将所有内容都用'''xx'''引号引起来),并且最后出现错误消息。它什么也没做,但是:吓人。然后我意识到在编辑它时,单引号可以跨越多行。因此,让我们只将块分配给变量。

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

ls -l
date

'

只是无需将其分配给变量,这我们不会从“注释”中获得的副作用。用x=a 代替: ,您将具有相同的效果而没有副作用。唯一的缺点是注释不能包含单引号。这就是为什么我更喜欢使用带引号的heredoc:注释者可以根据需要选择合适的终止字符串。
user1934428

2

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

暂时阻止脚本的一部分:

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

-2

#我喜欢懒惰和简单。我将#与有趣的解决方法结合使用:

1按:]查找ctrl + F或cmd + F或其他[以触发查找功能

2在查找字段中使用正则表达式,例如: (^.+)

3替换为:# $1或者,如果您愿意#$1


#注意:您的编辑器中可能没有这三个步骤。在这种情况下,请使用在线正则表达式工具(出于政策原因,在此处不能建议一个):

  1. 选择并复制文本,无论您身在何处,然后将其粘贴到在线正则表达式工具中
  2. 使用(^.+)的正则表达式和#$1#\1作为替代模式
  3. 选择,复制文本并将其粘贴回开始的位置

#享受您的哈希!


如今ctrl+/,许多编辑器都具有热键,即使在多行中也可以打开或关闭注释。它还可以根据您使用的语言来更改注释字符。
ninMonkey
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.