如何理解tee命令?

sto*_*ren 1 bash

我的目录有四个文件:

1 2 3 4 
Run Code Online (Sandbox Code Playgroud)

然后我跑命令

ls | tee >(ls) | more
Run Code Online (Sandbox Code Playgroud)

它会打印出来

1
3
2
4
1
2
3
4
Run Code Online (Sandbox Code Playgroud)

但是当我跑

ls | tee>(echo hello) | more
Run Code Online (Sandbox Code Playgroud)

只有

hello
Run Code Online (Sandbox Code Playgroud)

为什么?在第一个命令中,第一个ls的结果将被定向到更多,第二个ls的结果也将被定向到更多.但是在第二个命令中,为什么ls的结果不是针对更多?

顺便说一句,是什么意思?

Jon*_*art 5

通常>是用于将标准重定向到文件的运算符.在这里,它使用Bash的一个功能,称为进程替换,它允许您将进程的标准输入或输出替换为预期的输出文件或输入文件(分别).

开球

通常,tee会将其标准输入写入您告诉它的文件名,以及它的标准输出.它有效地在数据管道中放置了"T".

foo | tee foo.out | bar
Run Code Online (Sandbox Code Playgroud)

结果是:

foo --> tee --> bar
         |
         V
      foo.out
Run Code Online (Sandbox Code Playgroud)

流程替代

进程替换是Bash的一个特性,它使shell打开一个命名管道到您的进程替换文件,并传递该命名管道代替文件名.例:

diff <(echo hello) <(echo goodbye)
Run Code Online (Sandbox Code Playgroud)

结果是

echo hello > /dev/fd/63 &
echo hello > /dev/fd/62 &
diff /dev/fd/63 /dev/fd/62
Run Code Online (Sandbox Code Playgroud)

结合三通和工艺替代

ls | tee >(ls) | more
Run Code Online (Sandbox Code Playgroud)

没关系,因为ls甚至没有看它的标准输入.所以你有了:

ls < /dev/fd/63 &       # which never gets read

ls --> tee --> more
        |
        V
    /dev/fd/63
Run Code Online (Sandbox Code Playgroud)

所以首先你看到ls括号输出你的目录列表(它永远不会读取你给它的标准输入).然后你看到more打印第一个输出ls.输出tee丢失,因为您将其发送给另一个ls.结果?输出ls 两次.