我试图解释以下tee
命令:
cat colors.txt words.txt | tee colorsAndWords.txt | wc
我的如下理解正确吗?
cat colors.txt words.txt
colors.txt
:此命令连接和文件的内容words.txt
并将组合输出发送到标准输出(终端)。| tee colorsAndWords.txt
:(|
管道)符号获取前一个命令的输出并将其作为命令的输入传递tee
。tee
用于在标准输出(通常是终端)上显示数据并将其写入文件。在本例中,它将串联输出写入名为colorsAndWords.txt
.| wc
:final| wc
获取命令的输出tee
,仍然是连接的内容,并将其传递给命令wc
。wc
用于计算作为输入接收的文本中的行数、单词数和字符数。
答案1
你的理解是正确的,我看不出什么需要纠正关于tee
实用性。它用于复制数据流,您显示的示例就是这样做的,将一个副本存储在一个文件中(可能有很多),同时还将其传递到管道的下一阶段。
它是标准实用程序,这意味着它在任何 Unix 系统上都可以同样工作,而不仅仅是 Linux。其标准规格在这里找到,并且在 Linux 和其他地方找到的实现应该遵循该描述(但可能会添加扩展,例如新的命令行选项)。
答案2
对,那是正确的。 tee
就像水管中的 T 形接头,或者双输出耳机插孔分配器。它读取输入并将其复制到两个输出文件:stdout 和命令行上指定的文件。 (实际上,任意数量的输出文件;您可以在命令行上指定多个输出文件。本答案的其余部分假设一个参数的简单情况。)
也许这会有助于理解如何编写tee
.
在 C 中,循环体如下所示:
ssize_t bytes_read = read(0 /*stdin*/, buf, 4096);
write(1 /*stdout*/, buf, bytes_read); // error checking not shown; also
write(cmdline_arg_output_fd, buf, bytes_read); // loops to finish short writes
循环条件类似于while(bytes_read > 0)
捕获 EOF(读取返回 0)或错误(负数),可能类似于while( (bytes = read()) > 0 )
控制表达式内的赋值和比较。因为需要检查返回值前进行写调用。
在那个循环之前,fd = open(argv[1], O_WRONLY|O_CREAT, 0666);
或者其他什么。
一种有趣的用法是foo | bar | tee /dev/tty | baz
作为一种“调试打印”来查看数据通过管道的该阶段。 (打开/dev/tty
实际上会为您提供控制该进程的 TTY 的任何设备,即终端。就像/dev/pts/19
在 Konsole 终端选项卡中一样。)
其他有用的参数包括您正在使用的常规文件,以及命名管道,甚至是像>( grep ... > filtered.txt)
.
答案3
'|' 管道字符是向 shell 发出的指令,指示这三个程序 (cat、tee 和 wc) 应该以非常特定的方式运行。
他们基本上没有注意到 stdout(在本例中为 cat 和 tee)被重定向到不是终端本身的东西这一事实。
对于程序 tee 和 wc 的标准输入也是如此。