如何为多行命令添加行注释

Pet*_*Lee 303 bash shell comments

我知道如何在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
Run Code Online (Sandbox Code Playgroud)

但不幸的是,继续角色之后的评论\将打破命令.

Mar*_*agh 573

我就是这样做的.基本上通过使用Bash的反引号命令替换,可以将这些注释放在长命令行的任何位置,即使它是跨行分割的.我已将echo命令放在您的示例前面,以便您可以执行该示例并查看其工作原理:

echo CommandName InputFiles `#1st comment` \
             --option1 arg1 `#2nd comment` \
             --option2 arg2 `#3rd comment`
Run Code Online (Sandbox Code Playgroud)

另一个例子,您可以在一行的不同点放置多个注释:

some_cmd --opt1 `#1st comment` --opt2 `#2nd comment` --opt3 `#3rd comment`
Run Code Online (Sandbox Code Playgroud)

  • 这是我见过的最巧妙的替代滥用行为! (195认同)
  • 这些注释非常昂贵,因为它们中的每一个都创建了一个子shell.这使得该技术在某些情况下无法使用.使用相同基本思想的便宜得多的,如果不太可读的替代方案是:`echo CommandName InputFiles $ {IFS#1st comment} --option1 arg1 $ {IFS#2nd comment} --option2 arg2 $ {IFS#3rd comment} `. (47认同)
  • 这种技术为每个内联注释创建一个子shell,因此这些是非常昂贵的注释.它们仅适用于不经常执行的行. (22认同)
  • 有趣的是它如何仅与反引号一起使用,而不是在使用`$()`使用命令替换时.有什么理由吗? (9认同)
  • 它甚至可以在管道子命令中运行:"echo \`#1 \`foo \\(换行)| perl -ne \`#2 \`'print'"......正是我需要的! (8认同)
  • @pjh,不适用于所有shell.`dash`在没有命令的情况下优化了fork和pipe for命令替换,并且`ksh93`不为子shell分叉(并且只在需要执行外部命令时才创建管道) (6认同)
  • 对我来说,当我想在脚本文件中阻止长多行命令中某些选项的操作时,快速解决问题很有用. (3认同)
  • 只是不要使用任何包含命令终止符的注释,如`;`或`&`. (3认同)
  • @pjh 有关“${IFS#Comments}”的潜在问题,请参阅[此处](/sf/answers/3316182131/)。 (3认同)
  • @phk *“有趣的是,它仅适用于反引号,而使用$()进行命令替换时则无效。是否有任何原因?” *一旦$()看到了#号,该行的其余部分将被视为注释,并且括号永远不会关闭。反引号的解析方式有所不同。您可以改为执行$(:评论)。/sf/ask/101919191/#56979539 (2认同)

Phi*_*ipp 73

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

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[@]}"
Run Code Online (Sandbox Code Playgroud)

但是,我认为如果只是为了允许每个参数的注释,这看起来有点hackish.因此,我只是重写注释,以便引用各个参数,并将其置于整个命令之上.

  • 不太讨厌只是将*arguments*存储在数组中,然后像这样使用它们:`CommandName"$ {args [@]}"`. (9认同)
  • 这适用于像OP的例子那样简单的东西,但它不支持`>`和`<`和`|`以及`||`和`&&`等等. (5认同)
  • @PeterLee:您也可以在数组中使用“”和“”。 (2认同)
  • 如果您希望能够在参数列表中注释掉整行,则此格式优于所有其他格式.`command"$ {args [@]}"`ftw. (2认同)

Per*_*rry 63

我担心,一般来说,你不能做你所要求的.您可以做的最好是对命令前面的行进行注释,或者在命令行末尾添加一条注释,或者在命令后注释.

您无法以这种方式在命令中散布注释.在\小号表达的意图,合并线路,所以对于所有意图和目的你想在单行线,不反正工作,因为一来点缀评论\必须是在该行的末尾有这种效果.

  • 接受的答案应该是 Marwan 的下面。 (11认同)
  • 更不用说"`'有效地合并这些行"甚至不对,问题是反斜杠必须紧接在换行符之前才能逃避它,而使用`cmd \#comment`则有空格和在反斜杠和换行符之间进行注释. (4认同)
  • 我认为我不同意,Marwan的答案很聪明,但感觉像是在替代替代品。如果有什么我想说的,Philipp的答案更接近我想做的事情。 (2认同)
  • 事实上,这个答案被标记为已接受的答案,而 Marwan 的答案则被推荐反对,理由是与 99%(性能)/100%(“感觉错误”)来这里寻找“解决方案”的用户无关,这既令人悲伤又令人沮丧。代表软件开发出了什么问题。 (2认同)

che*_*ner 16

基于pjh对此问题的另一个答案的评论,替换IFS为已知不包含非空白字符的变量.

comment=
who ${comment# This is the command} \
    -u ${comment# This is the argument}
Run Code Online (Sandbox Code Playgroud)

  • 对于 `${parameter#word}` [POSIX 指定](https://pubs.opengroup.org/onlinepubs/009604499/utilities/xcu_chap02.html#tag_02_06_02) *"word 应进行波形符扩展、参数扩展、命令替换和算术扩展”*并且有些含糊*“如果不需要单词,则不应扩展”*。如果 `$parameter` 为空,bash 不会扩展 `word` 但仍然解析它。因此,注释需要正确的 shell 语法,即使它们没有被执行。**示例:** `echo ${comment# 12" (inch) are 1' (foot)}` 会导致“在查找匹配的 '"'`` 时出现意外的 EOF。 (2认同)