“cat < EOF | grep”在 bash 中如何工作?

“cat < EOF | grep”在 bash 中如何工作?

这个答案“cat << EOF”在 bash 中如何工作?在 Stack Overflow 上,我得到了前两点。但我不明白第三点将多行字符串传递到 Bash 中的管道

  1. 将多行字符串传递到 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(比较这个答案)因为如果您从左到右阅读,那么它将严格对应于数据的流动方式:这里的文档catgreptee

请注意,这一切都可以在没有以下内容的情况下完成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

catcat | 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

相关内容