我知道如何在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

但不幸的是,在继续字符\后面的注释将中断命令。


当前回答

根据pjh对这个问题的另一个答案的注释,将IFS替换为已知不包含非空格字符的变量。

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

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

不带引号的参数展开会进行分词和生成路径名。在本例中,两个进程都不会从空字符串中创建任何额外的单词,因此结果仍然是空字符串。这样的空字符串将被直接丢弃,而不会影响它所在的命令。以上正好相当于

who \
  -u

其他回答

根据pjh对这个问题的另一个答案的注释,将IFS替换为已知不包含非空格字符的变量。

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

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

不带引号的参数展开会进行分词和生成路径名。在本例中,两个进程都不会从空字符串中创建任何额外的单词,因此结果仍然是空字符串。这样的空字符串将被直接丢弃,而不会影响它所在的命令。以上正好相当于

who \
  -u

你可以将参数存储在一个数组中:

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[@]}"

然而,我认为这看起来有点笨拙,如果它只是为了允许每个参数的注释。因此,我重写了注释,使其引用各个参数,并将其置于整个命令之上。

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

您无法通过这种方式在命令中穿插注释。\表示合并行的意图,因此无论如何,您都试图在单行中散布注释,这无论如何都不起作用,因为\必须在行末才能产生这种效果。

我就是这么做的。实际上,通过使用Bash的反标记命令替换,可以将这些注释放置在长命令行的任何位置,即使它是跨行分割的。我把echo命令放在你的例子前面,这样你就可以执行这个例子,看看它是如何工作的:

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

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

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