我熟悉这种语法:
cmd1 << EOF | cmd2
text
EOF
但我刚刚发现bash允许我这样写:
cmd1 << EOF |
text
EOF
cmd2
(heredoc 用作输入到 cmd1 中,而 cmd1 的输出被管道传输到 cmd2)。这似乎是一种非常奇怪的语法。它是否可移植?
是的,POSIX标准允许这样做。根据2008版本的规定:
Here-document应被视为一个单词,它从下一个
<newline>
开始,一直持续到只包含定界符和<newline>
的行,其中没有任何<blank>
字符。然后,如果有下一个here-document,则开始下一个。
并包括同一行中多个 "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 */
所以,管道符号可以跟随行尾并仍被视为管道线的一部分。是的,它在POSIX shell语法中。您还可以为同一命令拥有多个here-doc(其他示例使用两个cat
调用,但这也可以工作):
cat <<EOF1 <<EOF2
first here-doc
EOF1
second here-doc
EOF2
这是一个人为的例子(使用两个 here-docs 作为标准输入),但如果你考虑为不同的文件描述符提供输入,它立即就有意义了。
还有一种可能性是drop the cat
entirely
。为什么不直接将 here-document 提供给 cmd
:cmd << EOF
input
here
EOF
cat <
- user1424739sudo tee /etc/securefile.conf <<EOF
时,这非常方便。 - dragon788嗯,根据在 POSIX 模式下在 bash 中的测试,我想是的:
$ bash --posix
$ cat <<EOF |
> ahoj
> nazdar
> EOF
> sed 's/a/b/'
bhoj
nbzdar
EOF
后面加任何空格。否则命令提示符会表现奇怪,你会想弄清楚到底出了什么问题。 - Sridhar Sarnobat嗨,以此为例进行检查
#!/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
。这种“奇怪的语法”似乎是最好的方式。 - PaulC