提问人:William Pursell 提问时间:8/13/2011 最后编辑:William Pursell 更新时间:3/21/2019 访问量:52913
用于管道 heredoc 的多行语法;这是便携式的吗?
Multiline syntax for piping a heredoc; is this portable?
问:
我熟悉这个语法:
cmd1 << EOF | cmd2
text
EOF
但刚刚发现 bash 允许我写:
cmd1 << EOF |
text
EOF
cmd2
(HereDoc 用作 cmd1 的输入,cmd1 的输出通过管道传递给 cmd2)。这似乎是一个非常奇怪的语法。它是便携式的吗?
答:
19赞
Tomas
8/13/2011
#1
嗯,我想是的,根据 POSIX 模式下 bash 中的测试:
$ bash --posix
$ cat <<EOF |
> ahoj
> nazdar
> EOF
> sed 's/a/b/'
bhoj
nbzdar
评论
0赞
Sridhar Sarnobat
1/5/2018
还有一个小注意事项:不要在关闭后放置任何空格。提示会表现得很奇怪,你会想知道到底出了什么问题EOF
2赞
Charles Duffy
1/5/2018
在 POSIX 模式下运行 bash 会关闭一些扩展,但绝不会关闭几乎所有扩展。因此,虽然这个答案在POSIX允许的范围内是正确的,但它的推理并不能非常有效地支持这一点。
121赞
Ned Deily
8/13/2011
#2
是的,POSIX标准允许这样做。根据 2008 年版本:
此处文档应被视为一个单词,开头在 下一个并继续,直到有一行只包含 分隔符和 a ,中间没有字符。 然后,如果有,则开始下一个 here-document。
<newline>
<newline>
<blank>
并在同一行中包含多个“here-documents”的示例:
cat <<eof1; cat <<eof2
Hi,
eof1
Helene.
eof2
因此,进行重定向或管道没有问题。您的示例类似于以下内容:
cat file |
cmd
shell 语法(在链接页面的下方)包括以下定义:
pipe_sequence : command
| pipe_sequence '|' linebreak command
newline_list : NEWLINE
| newline_list NEWLINE
;
linebreak : newline_list
| /* empty */
因此,管道符号后跟行尾,仍可被视为管道的一部分。
28赞
Jens
5/21/2012
#3
是的,它在 POSIX shell 语法中。对于同一命令,您还可以有多个 here-doc(其他一些示例使用两个调用,但这也有效):cat
cat <<EOF1 <<EOF2
first here-doc
EOF1
second here-doc
EOF2
这是人为的(使用 2 个 here-docs 作为 stdin),但如果您考虑为不同的文件描述符提供输入,它会立即变得有意义。
也有可能完全放下猫
。为什么不将 here-document 直接提供给:cmd
cmd << EOF
input
here
EOF
评论
1赞
user1424739
6/1/2015
''' cat <<EOF1 <<EOF2 first here-doc EOF1 second here-doc EOF2 ''' 以上不起作用。
0赞
Jens
6/1/2015
@user1424739 它确实适用于当前的 zsh 和 bash。ash 和 ksh93 似乎只输出第二个 here 文档。
0赞
Jens
1/2/2017
为什么投反对票?如果有不准确的地方,请给我机会进行补救。
0赞
dragon788
7/20/2017
这在使用时非常贴心。sudo tee /etc/securefile.conf <<EOF
3赞
huelbois
7/5/2019
它在什么 bash 版本上工作?使用 bash 4.4.19(在 ubuntu 18.04.02 上)和 bash 5.0(docker 镜像),我只得到了第二个 here-doc。或者也许有一个特定的选择?
9赞
buc
3/21/2019
#4
嗨,例如,检查一下
#!/bin/sh
( base32 -d | base64 -d )<<ENDOFTEXT
KNDWW42DNNSHS5ZXPJCG4MSVM5MVQVT2JFCTK3DELBFDCY2IIJYGE2JUJNHWS22LINVHQMCMNVFD
CWJQIIZVUV2JOVNEOVJLINTW6PIK
ENDOFTEXT
问候
评论
big-long-command1 with lots of args << EOF | big-long-command2 with lots of args