可以在bash中使用多个here-docs吗?


14

可以使用多个here-docs在bash中为命令提供输入吗?

$ cat <<<foo <<<bar
bar
$ cat <<EOF1 <<EOF2
> foo
> EOF1
> bar
> EOF2
bar

显然,在两种情况下,第二个here-doc都用作stdin,并替换了第一个引用。是使用echos 的解决方案吗?

$ cat <(echo -n foo) <(echo bar)
foobar

另外,由于某种原因,使用组合对我不起作用。为什么会这样呢?

$ cat <<<foo <(echo bar)
bar
$ cat <(echo -n foo) <<<bar
foo

您要使用两个此处文档而不是将其组合成一个事实,这背后没有任何原因吗?
2014年

1
paste使用虚拟输入进行测试时,我实际上遇到了@beans 。我想我还能想到其他几种情况。例如,如果我有一个脚本,其中包含一些变量的预操作文本,那么我可能想使用仅接收文件的命令对两者进行处理diff
Sparhawk

另一个用例(我发现这个在这里使用,文档创建一个shell脚本):你要几行变量扩展,然后一些无行:cat <<EOF1 <<"EOF2"
Toby Speight

Answers:


18

你可以做:

cat /dev/fd/3 3<< E1 /dev/fd/4 4<< E2
foo
E1
bar
E2

只能有一个stdin,因为只有一个文件描述符0。

cat << EOF
eof
EOF

的缩写:

cat /dev/fd/0 0<< EOF
eof
EOF

和:

cat <<< foo

是:

cat /dev/fd/0 0<<< foo

您必须确定要在文件描述符0上打开什么。

cat <(echo foo)

是:

cat /dev/fd/123

其中123是管道的文件描述符,并且bash echo foo在另一个进程中并行运行,且stdout重定向到管道的另一端。

将文件名传递给后catcat不再从stdin中读取。您需要:

cat <(echo foo) /dev/fd/0 << EOF
bar
EOF

要么:

cat <(echo foo) - << EOF
bar
EOF

-是告诉cat从stdin读取)。


1
cat <<EOFcat /dev/fd/0...:并不完全相同:在后一种情况下,会cat看到文件名并打开。
Mikel 2014年

@Mikel,我的意思是它在功能上等效的。如果未传递任何参数,cat则从其fd0 读取,就好像传递了-or一样/dev/fd/0(尽管在Linux(仅Linux)上,打开/dev/fd/0并不完全像复制文件描述符0一样)。
斯特凡Chazelas

我对/dev/fd/3 3<< E1构造感到非常惊讶,现在我想知道/ dev / fd /下的项目到底是什么。尽管进程以某种方式神奇地显示了文件,但在文件系统上某个地方打开文件后,每个进程默认存在的1和2除外。但是在您的示例中,您使用的是文件描述符3和4,除了输入重定向以外,它们未连接到任何实际文件。我在文件描述符的心理模型中无法理解这一点。如果进程想要打开另一个文件,它将知道必须使用fd 5怎么办?fds是否必须为3、4、5 ..或可以为任何其他值?
calavera.info

@ calavera.info,听起来您想创建一个后续问题。
斯特凡Chazelas
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.