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

Wie*_*err 100 bash shell-script

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

echo a
#
: aaa 
: ddd 
#
echo b
Run Code Online (Sandbox Code Playgroud)

这似乎有效,甚至vim语法突出显示它。这种评论风格是什么,我如何找到有关它的更多信息?

jw0*_*013 145

那不是多行注释。 #是单行注释。 :(colon)根本不是注释,而是一个 shell 内置命令,它基本上是一个NOP,一个空操作,除了返回 true 之外什么都不做,就像true(因此设置$?为 0 作为副作用)。然而,由于它是一个命令,它可以接受参数,并且由于它忽略了它的参数,在大多数情况下,它表面上就像一个注释。这种混乱的主要问题是争论仍在扩大,导致许多意想不到的后果。参数仍然受语法错误的影响,仍然会执行重定向,因此: > file将 truncate file,并且: $(dangerous command)替换仍然会运行。

在 shell 脚本中插入注释的最不令人惊讶的完全安全的方法是使用#. 即使对于多行注释,也要坚持这一点。 切勿尝试 (ab):用于评论。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
Run Code Online (Sandbox Code Playgroud)

  • +1 将单引号保留在 `&lt;&lt;` 行上非常重要 - 这会关闭替换和扩展。 (30认同)
  • 作为额外的注意事项,用 `:` 填充 shell 脚本来处理应该是注释的内容会导致额外的 RAM/CPU 消耗。它不会处理桌面上的简单事情,但如果它每秒执行数百或数千次,您将 [什么都不做,速度很快](http://www.kethinov.com/startrekepisodes.php?系列=1&amp;季节=3&amp;epnumber=15)。 (4认同)
  • @bahamat:如果您每秒执行数百或数千次,我希望您不会在 shell 中编写它... =/ (3认同)

Ign*_*ams 29

这不是任何评论风格。在:内置的命令绝对没有; 在这里评论被滥用了。

$ help :
:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.
Run Code Online (Sandbox Code Playgroud)


小智 26

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

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

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

: $(command) # executes 'command'
Run Code Online (Sandbox Code Playgroud)

(有时冒号仅用于调用这些副作用,但它不会被用作注释。)

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

: '
while [ "$n" -ne "$x" ]
do
  : whatever
done
'
Run Code Online (Sandbox Code Playgroud)

这比在每一行前面加上 节省了大量时间#,特别是如果注释掉只是暂时的。

  • 这种单引号注释方法不适用于本身使用单引号的任何脚本部分。如果您尽可能多地使用引号,这意味着您将在整个脚本中散布合法的单引号。使用任何体面的编辑器可以让您进行逐行注释,这要简单得多。 (3认同)