多行Shell脚本注释-这是如何工作的?


92

最近,我偶然发现了以前从未见过的多行注释类型-这是一个脚本示例:

echo a
#
: aaa 
: ddd 
#
echo b

这似乎是可行的,甚至在vim语法方面也很突出。这种评论方式叫什么,如何找到有关它的更多信息?


1
如果您将代码包装到函数中以将其注释掉怎么办?CommentedOutBlock() { echo "test"; }
Buksy

Answers:


135

那不是多行注释。 #是单行注释。 :(冒号)根本不是注释,而是shell内置命令,它基本上是NOP,是一个空操作,除了返回true外,不执行任何操作,例如true(因此设置$?为0作为副作用)。但是,由于它是命令,因此可以接受自变量,并且由于它忽略其自变量,因此在大多数情况下,它的表面行为类似于注释。这种冲突的主要问题是论点仍在扩展,导致许多意想不到的后果。参数仍然受到语法错误的影响,仍然执行重定向,因此: > file将截断file,并且: $(dangerous command)替换仍将运行。

在shell脚本中插入注释的最令人惊讶的完全安全的方法是使用#。即使是多行注释也要坚持下去。 切勿尝试(滥用):评论。Shell中没有专用的多行注释机制,类似于类语言中的斜杠星号/* */形式C


为了完整起见,但不是因为建议这样做,因此我将提到可以使用here-documents进行多行“注释”:

: <<'end_long_comment'
This is an abuse of the null command ':' and the here-document syntax
to achieve a "multi-line comment".  According to the POSIX spec linked 
above, if any character in the delimiter word ("end_long_comment" in 
this case) above is quoted, the here-document will not be expanded in 
any way.  This is **critical**, as failing to quote the "end_long_comment" 
will result in the problems with unintended expansions described above. 
All of this text in this here-doc goes to the standard input of :, which 
does nothing with it, hence the effect is like a comment.  There is very 
little point to doing this besides throwing people off.  Just use '#'.
end_long_comment

29
+1非常重要,以使单引号保持<<在线-这会关闭替换和扩展。
glenn jackman 2012年

4
另外要特别注意的是,在shell脚本中填入:应作为注释的内容会导致额外的RAM / CPU消耗。它不会满足于桌面上的简单操作,但是如果每秒执行数百次或数千次操作,您将无所作为,速度很快
bahamat 2012年

3
@bahamat:如果您每秒执行数百或数千次操作,希望您不要在shell中编写它……= /
7heo.tk 2014年

1
有时,对多行文本使用null实用程序可能会很有用。以注释开始: <<=cut,可以在shell脚本中编写POD,有关详细信息,请参见此示例。这样就可以使用perldoc script.sh。但是,此答案中显示的多行注释绝对应该是注释块(每行以开头# )。
basic6 2014年

这是一个关于heredocs的精彩讨论,用于注释和其他有趣的用例(甚至包括dynaimc脚本生成):tldp.org/LDP/abs/html/here-docs.html#EX71C
bguiz


25

在早期的shell中,冒号是创建注释的唯一方法。

但是,这不是真正的注释,因为该行的解析方式与其他命令的解析方式完全相同,并且可能会有副作用。例如:

: ${a:=x} # assigns the value 'x' to the variable, 'a'

: $(command) # executes 'command'

(有时,冒号仅用于引起这些副作用的目的,但并不用作注释。)

有时使用冒号注释掉脚本的一部分有时很方便:

: '
while [ "$n" -ne "$x" ]
do
  : whatever
done
'

与在每行之前添加相比#,这节省了很多时间,尤其是在注释只是暂时的情况下。


2
单引号注释方法不适用于本身使用单引号的脚本的任何部分。而且,如果您在尽可能多的地方使用引号,则意味着整个脚本中都会散布合法的单引号。只需使用任何可让您进行逐行注释的体面编辑器,都非常简单。
jw013

您说对了,只有在引用的部分中没有单引号的情况下,它才起作用。但是,脚本不必使用很多单引号。在查看我的一些脚本时,我发现它们相对稀疏,许多可以用双引号代替。
克里斯·约翰逊

单引号或双引号的选择应该几乎不受琐碎且无关紧要的问题的影响,例如脚本的文本本身是否是有效的单引号字符串。单引号用于防止扩展,而双引号则允许某些扩展并需要额外的分析。这是确定使用哪个的真正标准。
jw013

到目前为止,这是最时髦的方法。非常适合少量文档。我比它更喜欢它,/* */而且,不要让我开始<!-- -->
亚历克斯·格雷

1

如果您的注释在脚本的末尾,则可以这样进行:

#!/bin/sh
echo 'hello world'
exec true
we can put whatever we want here
\'\"\$\`!#%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
abcdefghijklmnopqrstuvwxyz{|}~
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.