![“cat < EOF | grep”在 bash 中如何工作?](https://linux22.com/image/200423/%E2%80%9Ccat%20%3C%20EOF%20%7C%20grep%E2%80%9D%E5%9C%A8%20bash%20%E4%B8%AD%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C%EF%BC%9F.png)
在这个答案到“cat << EOF”在 bash 中如何工作?在 Stack Overflow 上,我得到了前两点。但我不明白第三点将多行字符串传递到 Bash 中的管道
将多行字符串传递到 Bash 中的管道
$ cat <<EOF | grep 'b' | tee b.txt foo bar baz EOF
因为它有 3 个单词,2 个管道字符。然后我不知道如何解释它。
答案1
从你的评论来看:
我不确定第一个管道符(“|”)的作用是什么?
第一个|
字符将 的输出连接cat
到 的输入grep
。<<
重定向输入的cat
;这是一个完全独立的重定向,<
类似于cat <some_file | grep …
.
您可能更喜欢<<EOF cat | grep 'b' | tee b.txt
(比较这个答案)因为如果您从左到右阅读,那么它将严格对应于数据的流动方式:这里的文档→ cat
→ grep
→ tee
。
请注意,这一切都可以在没有以下内容的情况下完成cat
:
<<EOF grep 'b' | tee b.txt
foo
bar
baz
EOF
(或者grep 'b' <<EOF | …
)。
答案2
你正在使用的<< EOF
是特雷多克。
多行字符串被写入临时文件,然后成为标准输入的/bin/cat
过程。的输出cat
(即多行字符串)通过管道传送到 ,grep
而其输出又通过管道传送到tee
。
答案3
作为heredoc语法的进一步示例:
cat <<EOF1 | cat /proc/self/fd/3 - 3<<EOF2 | cat /proc/self/fd/3 - 3<<EOF3
foo
EOF1
bar
EOF2
baz
EOF3
输出
baz
bar
foo
人们一开始可能会认为在定界文档重定向之后需要立即提供定界文档,但事实并非如此。人们可以继续编写命令,甚至提供进一步的heredoc重定向。这意味着您可以将命令放在一处,而无需重定向迫使您将其拆分到可能很长的heredocs之后。
答案4
cat
cat | grep
链中存在冗余。这是新手复制粘贴其他新手的标志。
grep
(或任何其他工具)可以很好地接受输入,而无需cat
:
grep PATT <<EOF
...
EOF
Shell 语法允许在命令之前或之后指定 IO 重定向:
<<EOF grep OK - <(echo "OK 2")
OK 1
EOF
它打印(从 HERE 文档中搜索 stdin,由 指定-
;然后从进程替换中搜索命名管道,由 指定<()
):
(standard input):OK 1
/dev/fd/63:OK 2
您可以拥有任意数量的 HERE-doc,只需将数据转发到不同的文件描述符,并复制重定向最新的“胜利”(下面的打印OK3
):
<<EOF1 <<EOF2 cat <<EOF3
OK1
EOF1
OK2
EOF2
OK3
EOF3
打开流 3、向其写入数据并稍后读取它的示例(注意<&N
将描述符重定向N
到描述符的语法0
,即stdin
):
exec 3<<EOF
> OK
> EOF
cat <&3
OK
可以通过proc
文件系统引用进程的文件描述符/proc/self/fd/N
(确保您了解self
分叉进程时是什么!):
<<EOF cat | cat - /proc/self/fd/3 3<<EOF3 | cat - /proc/self/fd/4 4<<EOF4
> OK 1
> EOF
> OK 2
> EOF3
> OK 3
> EOF4
OK 1
OK 2
OK 3