在多行命令中的 Bash 脚本中注释

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1455988/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:33:18  来源:igfitidea点击:

Commenting in a Bash script inside a multiline command

bashsyntaxcomments

提问by BassKozz

How can I comment on each line of the following lines from a script?

如何评论脚本中的以下每一行?

cat ${MYSQLDUMP} | \
sed '1d' | \
tr ",;" "\n" | \
sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' | \
sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' | \
sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$//' | \
tr "\n" "," | \
sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n/g' -e 's/,$//' | \
sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}

If I try and add a comment like:

如果我尝试添加如下评论:

cat ${MYSQLDUMP} | \ # Output MYSQLDUMP File

I get:

我得到:

#: not found

Is it possible to comment here?

可以在这里发表评论吗?

回答by DigitalRoss

This will have some overhead, but technically it does answer your question:

这会有一些开销,但从技术上讲,它确实回答了您的问题:

echo abc `#Put your comment here` \
     def `#Another chance for a comment` \
     xyz, etc.

And for pipelines specifically, there is a clean solution with no overhead:

特别是对于管道,有一个没有开销的干净解决方案:

echo abc |        # Normal comment OK here
     tr a-z A-Z | # Another normal comment OK here
     sort |       # The pipelines are automatically continued
     uniq         # Final comment

See Stack Overflow question How to Put Line Comment for a Multi-line Command.

请参阅堆栈溢出问题如何为多行命令添加行注释

回答by mob

The trailing backslash must be the last character on the line for it to be interpreted as a continuation command. No comments or even whitespace are allowed after it.

尾随反斜杠必须是行中的最后一个字符,才能将其解释为继续命令。后面不允许有任何注释甚至空格。

You should be able to put comment lines in between your commands

您应该能够在命令之间添加注释行

# output MYSQLDUMP file
cat ${MYSQLDUMP} | \
# simplify the line
sed '/created_at/d' | \
# create some newlines
tr ",;" "\n" | \
# use some sed magic
sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' | \
# more magic
sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' | \
# even more magic
sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$//' | \
tr "\n" "," | \
# I hate phone numbers in my output
sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n/g' -e 's/,$//' | \ 
# one more sed call and then send it to the CSV file
sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}

回答by mob

As DigitalRoss pointed out, the trailing backslash is not necessary when the line woud end in |. And you can put comments on a line following a |:

正如 DigitalRoss 指出的那样,当行以|. 您可以在 a 后面的一行中添加注释|

 cat ${MYSQLDUMP} |         # Output MYSQLDUMP file
 sed '1d' |                 # skip the top line
 tr ",;" "\n" | 
 sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' |
 sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' |
 sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$//' |
 tr "\n" "," |
 sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n/g' -e 's/,$//' |   # hate phone numbers
 sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}

回答by tobiasvl

The backslash escapes the #, interpreting it as its literal character instead of a comment character.

反斜杠对 # 进行转义,将其解释为它的文字字符而不是注释字符。

回答by Tom Hale

$IFScomment hacks

$IFS评论黑客

This hack uses parameter expansionon $IFS, which is used to separate words in commands:

这个 hack 使用参数扩展on $IFS,用于分隔命令中的单词:

$ echo foo${IFS}bar
foo bar

Similarly:

相似地:

$ echo foo${IFS#comment}bar
foo bar

Using this, you can put a comment on a command line with contination:

使用它,您可以在命令行上添加注释:

$ echo foo${IFS# Comment here} \
> bar
foo bar

but the comment will need to be before the \continuation.

但评论需要在\继续之前。

Note that parameter expansion is performed inside the comment:

请注意,参数扩展是在注释中执行的:

$ ls file
ls: cannot access 'file': No such file or directory
$ echo foo${IFS# This command will create file: $(touch file)}bar
foo bar
$ ls file
file

Rare exception

罕见异常

The only rare case this fails is if $IFSpreviously started with the exact textwhich is removed via the expansion (ie, after the #character):

失败的唯一罕见情况是,如果$IFS之前以通过扩展(即,在字符之后)删除的确切文本开始#

$ IFS=x
$ echo foo${IFS#y}bar
foo bar
$ echo foo${IFS#x}bar
foobar

Note the final foobarhas no space, illustrating the issue.

注意 finalfoobar没有空格,说明了这个问题。

Since $IFScontains only whitespace by default, it's extremelyunlikely you'll run into this problem.

由于$IFS默认情况下仅包含空格,因此您不可能遇到此问题。



Credit to @pjh's commentwhich sparked off this answer.

感谢@ PJH的评论这引发了这样的回答。

回答by wisbucky

In addition to the examples by DigitalRoss, here's another form that you can use if you prefer $()instead of backticks `

除了 DigitalRoss 的示例之外,如果您愿意,可以使用另一种形式$()而不是反引号`

echo abc $(: comment) \
     def $(: comment) \
     xyz

Of course, you can use the colon syntax with backticks as well:

当然,您也可以使用带有反引号的冒号语法:

echo abc `: comment` \
     def `: comment` \
     xyz


Additional Notes

补充说明

The reason $(#comment)doesn't work is because once it sees the #, it treats the rest of the line as comments, including the closing parentheses: comment). So the parentheses is never closed.

原因$(#comment)不起作用是因为一旦它看到#,它会将行的其余部分视为注释,包括右括号:comment)。所以括号永远不会关闭。

Backticks parse differently and will detect the closing backtick even after a #.

反引号的解析方式不同,即使在#.

回答by John Sidles

Here is a bash script that combines the ideas and idioms of several previous comments to provide, with examples, inline comments having the general form ${__+ <comment text>}.

这是一个 bash 脚本,它结合了之前几个评论的想法和习惯用法,通过示例提供了具有一般形式的内联评论${__+ <comment text>}

In particular

特别是

  • <comment text>can be multi-line
  • <comment text>is not parameter-expanded
  • no subprocesses are spawned (so comments are efficient)
  • <comment text>可以是多行
  • <comment text>没有参数扩展
  • 没有产生子进程(所以注释是有效的)

There is one restriction on the <comment text>, namely, unbalanced braces '}'and parentheses ')'must be protected (i.e., '\}'and '\)').

有一个限制<comment text>,即必须保护不平衡的大括号'}'和括号')'(即,'\}''\)')。

There is one requirement on the local bash environment:

本地 bash 环境有一个要求:

  • the parameter name __must be unset
  • 参数名称__必须未设置

Any other syntactically valid bash parameter-name will serve in place of __, provided that the name has no set value.

任何其他语法上有效的 bash 参数名都将代替__,前提是该名称没有设置值。

An example script follows

示例脚本如下

# provide bash inline comments having the form
#     <code> ${__+ <comment>} <code> 
#     <code> ${__+ <multiline
#                   comment>} <code>

# utility routines that obviate "useless use of cat"
function bashcat { printf '%s\n' "$(</dev/stdin)"; }
function scat { 1>&2 bashcat; exit 1; }

# ensure that '__' is unset && remains unset
[[ -z ${__+x} ]] &&  # if '__' is unset
  declare -r __ ||   # then ensure that '__' remains unset 
  scat <<EOF         # else exit with an error
Error: the parameter __='${__}' is set, hence the
  comment-idiom '${__+ <comment text>}' will fail
EOF

${__+ (example of inline comments)
------------------------------------------------
the following inline comment-idiom is supported
    <code> ${__+ <comment>} <code> 
    <code> ${__+ <multiline
                  comment>} <code> 
(advisory) the parameter '__' must NOT be set;
  even the null declaration __='' will fail
(advisory) protect unbalanced delimiters \} and \) 
(advisory) NO parameter-expansion of <comment> 
(advisory) NO subprocesses are spawned
(advisory) a functionally equivalent idiom is 
    <code> `# <comment>` <code> 
    <code> `# <multiline
               comment>` <code>
however each comment spawns a bash subprocess
that inelegantly requires ~1ms of computation 
------------------------------------------------}