gpt4 book ai didi

bash - :'END'在bash中如何工作以创建多行注释 block ?

转载 作者:行者123 更新时间:2023-11-29 08:46:43 25 4
gpt4 key购买 nike

我找到了一个如何comment in bash script的好答案(通过@sunny256):

#!/bin/bash
echo before comment
: <<'END'
bla bla
blurfl
END
echo after comment

'分隔符周围的 'END很重要,否则块内的内容(例如 $(command)将被解析和执行。
这可能很难看,但它是有效的,我很想知道它是什么意思。有谁能简单地解释一下吗?我已经找到了 :的解释,即它不是op或true。但不管怎样,我认为没有行动或是真的是没有意义的。。。。

最佳答案

恐怕这个解释不那么“简单”,而更为“透彻”,但我们来解释一下。
注释的目标是不作为代码解释或执行的文本。
最初,UNIX shell本身没有注释语法。但是,它确实有空命令:(一旦磁盘上有一个实际的二进制程序,/bin/:),它会忽略它的参数,只会指示调用shell成功执行。实际上,它是true的同义词,看起来像标点符号而不是单词,因此您可以在脚本中放置这样的行:

: This is a comment

这不是一个传统的注释;它仍然是shell执行的实际命令。但既然指挥部什么也不做,那就肯定已经足够接近了:任务完成了!对吗?
问题是,除了作为一个命令运行外,该行仍被视为一个命令。最重要的是,词法分析——参数替换、单词分裂等等——仍然发生在那些注定要被忽略的参数上。这样的处理意味着您有可能在“comment”中出现语法错误,从而导致整个脚本崩溃:
 : Now let's see what happens next
echo "Hello, world!"
#=> hello.sh: line 1: unexpected EOF while looking for matching `''

这个问题导致了一个真正的注释语法的引入:现在熟悉的 #。从 #到行尾的所有内容都被shell完全忽略,因此您可以在那里放置任何您喜欢的内容,而不必担心语法的有效性:
 # Now let's see what happens next
echo "Hello, world!"
#=> Hello, world!

这就是Shell获取注释语法的方式。
但是,您正在寻找一个多行(块)注释,这种注释是由C或Java中的 /*引入的(以 */结尾)。不幸的是,shell没有这样的语法。注释一个连续行块的常规方法——我推荐的方法——就是在每个行前面加一个 #。但不可否认,这并不是一种特别“多线”的做法。
您找到的解决方案使用的是所谓的 here-document。语法 some-command <<whatever导致以下文本行(从命令后面的行开始,直到但不包括仅包含文本 whatever的下一行)被读取并作为标准输入馈送到 some-command。下面是“Hello,world”的另一个shell实现,它利用了这个特性:
cat <<EOF
Hello, world
EOF

如果你用我们的老朋友替换 cat,你会发现它不仅忽略了它的参数,而且忽略了它的输入:你可以给它任何你想要的东西,它仍然不会做任何事情(仍然表明它没有成功地做任何事情)。
但是,here文档的内容确实要经过字符串处理。因此,正如使用单行 :注释一样,here文档版本在非可执行代码中存在语法错误的风险:
#!/bin/sh -e 
: <<EOF
(This is a backtick: `)
EOF
echo 'In modern shells, $(...) is preferred over backticks.'
#=> ./demo.sh: line 2: bad substitution: no closing "`" in `

如您在代码中所看到的,解决方案是在介绍here文档(例如 :)的行上引用文档末尾的“sentinel”(The EOFor ENDor whatever)。这样做会导致整个here文档体被视为文本-不会发生参数扩展或其他处理。取而代之的是,文本将以不变的方式输入到命令中,就像从文件中读取一样。因此,除了由哨兵组成的行之外,here文档可以包含任何字符:
#!/bin/sh -e
: <<'EOF'
This is a backtick: `
EOF
echo 'In modern shells, $(...) is preferred over backticks.'
#=> In modern shells, $(...) is preferred over backticks.

(值得注意的是,你引用哨兵的方式并不重要——你可以使用 <<'EOF'<<'EOF',甚至 <<E"OF";所有这些都有相同的结果。这与其他一些语言(如Perl和Ruby)中文档的工作方式不同,在这些语言中,内容的处理方式取决于引用sentinel的方式。)
尽管有上述任何一种情况,我强烈建议您只需在您想注释的每一行的前面加上一个 <<EO\F。任何一个好的代码编辑器都会使这个操作变得简单——甚至是简单的老代码——其好处是,没有人会阅读您的代码,而必须花费精力去弄清楚发生了什么事情,毕竟,这些事情是为了他们的利益而准备的文档。

关于bash - :'END'在bash中如何工作以创建多行注释 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32126653/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com