在多行命令中的 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
Commenting in a Bash script inside a multiline command
提问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
$IFS
comment 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 $IFS
previously 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 foobar
has no space, illustrating the issue.
注意 finalfoobar
没有空格,说明了这个问题。
Since $IFS
contains 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
------------------------------------------------}