用于传递Heredoc的多行语法;这是便携式的吗?


132

我熟悉以下语法:

cmd1 << EOF | cmd2
text
EOF

但是刚刚发现bash允许我写:

cmd1 << EOF |
text
EOF
cmd2

(heredoc用作cmd1的输入,而cmd1的输出通过管道传递到cmd2)。这似乎是一个非常奇怪的语法。便携吗?


我到这里来是找到一种将其分成多行的好方法: big-long-command1 with lots of args << EOF | big-long-command2 with lots of args。“奇数语法”似乎是最好的方法。
PaulC 2014年

一种方便的用例是,当您尝试将以空格分隔的表转换为以制表符分隔的表时,可以将其粘贴到Google Spreadsheets中。您无需创建临时文件。
Sridhar Sarnobat '18

第一个不适用于z-shell。我不喜欢第二个,因为它疏远了|。从命令中删除外壳管道的惯用语(?)。
Sridhar Sarnobat,

Answers:


104

是的,POSIX标准允许这样做。 根据2008版:

这里的文档应被视为一个单词,该单词从下一个单词开始<newline>,一直持续到一行仅包含定界符和a <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 */

因此,管道符号可以跟在行尾,但仍被视为管道的一部分。


26

是的,它在POSIX Shell语法中。对于同一命令,您还可以具有多个here-doc(其他示例使用两个cat调用,但这也可以):

cat <<EOF1 <<EOF2
first here-doc
EOF1
second here-doc
EOF2

这是人为设计的(对于stdin使用2个here-docs),但是如果您考虑为不同的文件描述符提供输入,则立即有意义。

也有可能完全删除cat。为什么不将此处文档直接提供给cmd

cmd << EOF
input
here
EOF

```cat << EOF1 << EOF2第一本文档EOF1第二本文档EOF2```以上操作无效。
user1424739 2015年

@ user1424739它确实可以在当前的zsh和bash中工作。ash和ksh93似乎仅在此处输出doc。
詹斯2015年

为什么要下票?如果有不正确的地方,请给我机会进行补救。
詹斯

使用时,这非常好sudo tee /etc/securefile.conf <<EOF
dragon788 '17

它在什么bash版本上起作用?使用bash 4.4.19(在ubuntu 18.04.02上)和bash 5.0(docker映像),我仅获得第二个here-doc。或者也许有一个特定的选择?
huelbois

17

嗯,我想是的,根据POSIX模式下bash中的测试:

$ bash --posix
$ cat <<EOF |
> ahoj
> nazdar
> EOF
> sed 's/a/b/'
bhoj
nbzdar

只是另外一个小小的注意事项:结束符后请勿放置任何空格EOF。提示的行为会很奇怪,您会想知道到底怎么了
Sridhar Sarnobat

2
在POSIX模式下运行bash会关闭某些扩展,但几乎不会关闭所有扩展。因此,尽管就POSIX所允许的观点而言,这个答案是正确的,但其推理并不十分有效。
查尔斯·达菲

3

嗨,例如,检查一下

#!/bin/sh
( base32 -d | base64 -d )<<ENDOFTEXT
KNDWW42DNNSHS5ZXPJCG4MSVM5MVQVT2JFCTK3DELBFDCY2IIJYGE2JUJNHWS22LINVHQMCMNVFD
CWJQIIZVUV2JOVNEOVJLINTW6PIK
ENDOFTEXT

问候

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.