如何为多行命令添加行注释[重复]

Posted

技术标签:

【中文标题】如何为多行命令添加行注释[重复]【英文标题】:How to put a line comment for a multi-line command [duplicate] 【发布时间】:2012-03-20 07:50:26 【问题描述】:

我知道如何在 Bash 脚本中编写多行命令,但是如何为多行命令中的每一行添加注释?

CommandName InputFiles      \ # This is the comment for the 1st line
            --option1 arg1  \ # This is the comment for the 2nd line
            --option2 arg2    # This is the comment for the 3nd line

但不幸的是,继续字符\ 之后的注释会破坏命令。

【问题讨论】:

将代码块复制到与之相邻的注释/注释块中,如果您更新代码,请记住更新注释块。 注意:这个问题及其解决方案也适用于多行字符串。 仅供参考,这不是this question 的重复,链接的问题是在询问使用管道的命令......而这个问题是在谈论一个有很多选项的命令。不是一回事。 用换行符替换#注释符号前的空格?您可以在 shell 脚本文件中将续行与注释行交替使用,而无需特殊技巧。 【参考方案1】:

根据 pjh 对another answer to this question 的评论,将IFS 替换为已知不包含非空白字符的变量。

comment=
who $comment# This is the command \
    -u $comment# This is the argument

为什么不引用参数扩展?变量用空字符串初始化。当发生参数扩展时,# 运算符(与 shell 注释字符 # 无关,但用于相似性)尝试从参数值中剥离实际注释。结果,当然,仍然是一个空字符串。

不带引号的参数扩展会经历分词和路径名生成。在这种情况下,两个进程都不会从空字符串创建任何额外的单词,因此结果仍然是空字符串。这样一个空字符串被简单地丢弃而不影响它出现的命令。以上正好等价于

who \
  -u

【讨论】:

这也是有问题的,因为它依赖于 not 在扩展周围使用双引号,因此它会随着分词而消失。这与教人们添加双引号的必要性背道而驰,这样当空格字符出现在数据中时,分词就不会弄乱它们。 我认为理解为什么引用几乎总是很重要很重要,以及理解为什么没有引用可能是故意的。 (也就是说,这是一个严重的 hack,我永远不会在我自己的 shell 脚本中实际使用它。) 是的,当然“为什么”也应该明白,可惜不是每个来看一段旧代码的人都能完全明白……而且sh语言好像不是最容易理解的,即使没有(咳咳)这样的创意解决方案。也就是说,我很高兴看到括号中的最后一句话。 For $parameter#word POSIX specifies "word 应进行波浪号扩展、参数扩展、命令替换和算术扩展" 有点模糊 "如果 word不需要,不得展开”。如果$parameter 为空,bash 不会扩展word,但仍会解析它。因此,cmets 需要正确的 shell 语法,即使它们没有被执行。 示例: echo $comment# 12" (inch) are 1' (foot) 导致 unexpected EOF while looking for matching `"'【参考方案2】:

这就是我的做法。本质上,通过使用 Bash 的反引号 command substitution,可以将这些 cmets 放置在长命令行的任何位置,即使它是跨行拆分的。我已将 echo 命令放在您的示例前面,以便您可以执行示例并查看它是如何工作的:

echo CommandName InputFiles `#1st comment` \
             --option1 arg1 `#2nd comment` \
             --option2 arg2 `#3rd comment`

另一个例子,你可以在一行的不同点放置多个 cmets:

some_cmd --opt1 `#1st comment` --opt2 `#2nd comment` --opt3 `#3rd comment`

【讨论】:

它甚至可以在管道子命令中工作:“echo `#1` foo \(newline) | perl -ne `#2` 'print'”...正是我需要的!跨度> 这是我见过的最巧妙的替代滥用! 这种技术为每个内联注释创建一个子shell,所以这些是非常昂贵的cmets。它们只适用于不经常执行的行。 这些 cmets 非常昂贵,因为它们每个都创建一个子 shell。这使得该技术在某些情况下无法使用。使用相同基本思想的更便宜但可读性更低的替代方案是:echo CommandName InputFiles $IFS# 1st comment --option1 arg1 $IFS# 2nd comment --option2 arg2 $IFS# 3rd comment 有趣的是,它只适用于反引号,但在使用 $() 的命令替换时不起作用。有什么原因吗?【参考方案3】:

您可以将参数存储在数组中:

args=(InputFiles      # This is the comment for the 1st line
      # You can have whole lines of comments in between, useful for:
      #--deprecated-option # This isn't use any more
      --option1 arg1  # This is the comment for the 2nd line

      # And even blank lines in between for readability
      --option2 arg2  # This is the comment for the 3nd line
     )
CommandName "$args[@]"

但是,如果仅出于允许每个参数使用 cmets 的目的,我认为这看起来有点 hackish。因此,我只需重写注释,使其引用各个参数,并将其放在整个命令之上。

【讨论】:

这适用于像 OP 的示例这样简单的东西,但它不支持 ><|||&& 等等。 @Philipp 嗯,谢谢。这是一个很好的解决方法。但如果我的--option arg 同时拥有'",恐怕会有点混乱。 @PeterLee:您也可以在数组中使用"' arguments 存储在数组中,然后像这样使用它们:CommandName "$args[@]". 如果您希望能够注释掉参数列表中的整行,则此格式优于所有其他格式。 command "$args[@]"ftw.【参考方案4】:

恐怕,一般来说,你不能做你所要求的。您可以做的最好的事情是在命令之前的行上添加注释,或者在命令行末尾添加一个注释,或者在命令之后添加注释。

您无法以这种方式在命令中散布 cmets。 \s 表达了合并行的意图,因此出于所有意图和目的,您试图将 cmets 散布在一行中,这无论如何都不起作用,因为 \ 必须位于行尾产生这种效果。

【讨论】:

更不用说“\ s 有效地合并这些行”甚至都不正确,问题是反斜杠必须紧跟在换行符之前才能转义它,而 @987654325 @ 在反斜杠和换行符之间有空格和注释。 接受的答案应该是 Marwan 的下面。 我认为我不同意,Marwan 的回答很聪明,但感觉像是滥用替代品。如果有什么我想说的话,菲利普的答案更接近我想做的事情。 还有另一种方法,它不涉及通过黑客攻击$IFS 的子shell:参见here。 这一事实被标记为已接受的答案,而建议不要使用 Marwan 的答案,理由是与 99%(性能)/100%(“感觉错误”)来这里寻找的用户无关for solutions 既可悲又代表了软件开发的问题。

以上是关于如何为多行命令添加行注释[重复]的主要内容,如果未能解决你的问题,请参考以下文章

bash命令跨越多行,中间有几行注释[重复]

vim的几种多行注释方法

idea复制多行加格式

如何为缺少的数据组合添加行并将相应的字段估算为 0

jQuery DataTables:如何为每个动态添加的行添加行 ID?

vim添加多行注释的几种方式