在 shell 脚本中注释掉一组代码行

54

我想知道是否有办法注释掉Shell脚本中的一组代码行。如何实现呢?在其他编程语言中,我们可以使用/* */实现此功能。这在转换/使用/修改其他脚本时非常有用,因为我想保留原始代码而不是将其删除。

找到并为所有未使用的代码行添加#号看起来很麻烦。

假设脚本中有100行连续的未使用代码行。 我想一次性将它们全部注释掉,这可行吗?


10个回答

49

最通用且安全的方法是将注释放入一个空的引用here-document中,如下所示:

<<"COMMENT"
    This long comment text includes ${parameter:=expansion}
    `command substitution` and $((arithmetic++ + --expansion)).
COMMENT

引用上述COMMENT分隔符是必要的,以防止参数扩展、命令替换和算术扩展。正如Bash手册所规定和POSIX shell标准指定的那样。
在上面的例子中,如果不引用COMMENT,则变量parameter将被赋予文本expansion,如果它为空或未设置,则执行命令command substitution,增加变量arithmetic并减少变量expansion
与其他解决方案相比:
使用if false; then comment text fi需要注释文本具有语法正确的Bash代码,而自然注释通常不是这样的,即使只是可能存在不平衡的撇号。同样适用于: || { comment text }结构。
将注释放入单引号的空命令参数中,例如:'comment text',缺点是无法包含撇号。双引号参数,例如:"comment text",仍然受到参数扩展、命令替换和算术扩展的影响,与未引用的这里文档内容一样可能导致上述副作用。

使用脚本和编辑器工具自动在块中每行前加上“#”具有一定的优点,但并不能完全回答问题。


47
if false
then

...code...

fi

false总是返回假,因此这将始终跳过代码。


3
Bash 不是一种预处理语言......在 C 中使用这个技巧作为预处理命令时非常有用。如果按照你所建议的方式使用它,将无法避免可能发生的语法错误。 - drAlberT
4
我其实不介意在“禁用”的代码中被告知语法错误。 - Artelius
6
在我看来,这绝不是最佳答案。 - Artelius
2
最佳答案在下面,由@asev69提供 - th3an0maly
1
@Artelius 有时候,你想要进行注释,因为目前你并不关心未解决的语法错误。 - th3an0maly

27

您也可以使用以下方法添加多行注释:

: '
comment1comment1
comment2comment2
comment3comment3
comment4comment4
'

根据Bourne Shell内置命令的Bash参考文档:

:(冒号)

: [参数]

除了扩展参数和执行重定向外,不执行任何操作。返回状态为零。

感谢Ikram在Shell脚本放置多行注释中指出这一点。

还需要注意的是,冒号和单引号之间有空格。尽管作者已经明确说明,但像我这样的一些人可能会忽略它,如果没有空格,程序将无法运行。 - ConfusedMan
我认为这是最好的答案。它非常清晰简洁。 - consuela
1
你可以使用 : ' : 来打开和关闭你的注释。 :) - Константин Ван
如果被注释的代码包含单引号,那么这种方法行不通且很危险。例如:: 'echo foo'<(echo bar >&2)'baz' - spbnick

21
您可以使用一个没有命令的“here”文档将其发送到某个地方。
#!/bin/bash
echo "Say Something"
<<COMMENT1
    your comment 1
    comment 2
    blah
COMMENT1
echo "Do something else"

维基百科参考资料


2
未使用引号的Here文档内容仍然会受到参数扩展、命令替换和算术扩展的影响,因此可能会产生副作用,例如将反引号中的文本作为命令执行。 - spbnick

10

文本编辑器有一个很棒的功能叫做搜索和替换。你没有说你使用的是哪个编辑器,但由于shell脚本倾向于*nix,而我使用VI,这里是注释一些Shell脚本第20到50行的命令:

:20,50s/^/#/

2
这就是我会做的方式。要取消注释,请尝试这样做::20,50s/^#// - Hai Vu

5
: || {
your code here
your code here
your code here
your code here
}

这并不比 if false; then … fi 更好,因为它不能将[可能存在的格式错误的]代码从语法分析中隐藏。 - Anton Samsonov

2

如果您将代码封装到函数中会怎样?

那么这个:

cd ~/documents
mkdir test
echo "useless script" > about.txt

变成这样:

CommentedOutBlock() {
  cd ~/documents
  mkdir test
  echo "useless script" > about.txt
}

1
根据此 site
#!/bin/bash
foo=bar
: '
This is a test comment
Author foo bar
Released under GNU 
'

echo "Init..."
# rest of script

0

根据您使用的编辑器,可能有一些快捷键可以注释一段代码。

另一个解决方法是将您的代码放在“if(0)”的条件块中 ;)


在Bash中,0是真值。如果我没记错的话,if (0); then将始终执行。 - sig_seg_v

-1
这个 Perl 单行命令将文件 orig.sh 中第 1 至 3 行(其中第一行编号为 0)注释掉,并将注释后的版本写入 cmt.sh
perl -n -e '$s=1;$e=3; $_="#$_" if $i>=$s&&$i<=$e;print;$i++' orig.sh > cmt.sh

显然,您可以根据需要更改边界数字。

如果您想直接编辑文件,则代码会更短:

perl -in -e '$s=1;$e=3; $_="#$_" if $i>=$s&&$i<=$e;print;$i++' orig.sh

演示

$ cat orig.sh 
a
b
c
d
e
f

$ perl -n -e '$s=1;$e=3; $_="#$_" if $i>=$s&&$i<=$e;print;$i++' orig.sh > cmt.sh

$ cat cmt.sh 
a
#b
#c
#d
e
f

sed 更简单:echo -e "1\n2\n3\n4\n5\n6" | sed -e "2,4 s/^/#/" - vp_arth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接