管道把小型命令连接起来,让数据无需中间文件即可在命令之间流动。tee 命令可以把这段流复制到文件,同时继续向后发送。
文本操作 · 第 4 课
管道和 tee
学习管道如何连接命令,以及 tee 如何保存数据流并继续向后传递。
使用 | 连接命令
让我们从一个产生大量输出的命令开始:
$ ls -la /etc
列表项可能太长,无法在屏幕上显示,难以阅读。虽然您可以将此输出重定向到文件,但更有效的方法是将其直接发送到另一个命令,例如 less,以便于查看。
$ ls -la /etc | less
shell 会启动管道中的命令并建立数据流连接。命令可以并发工作:ls 还没生成完整列表时,less 就能开始读取。
在 ls -la /etc | less 中,| 默认连接哪两条流?
保持 stderr 独立
普通 | 只传递 stdout。左侧命令的 stderr 保持原目标,通常是终端:
$ find /etc -name "*.conf" | less
匹配路径通过管道传递,权限诊断信息仍可能直接显示在终端。需要不同处理方式时,请单独重定向 stderr:
$ find /etc -name "*.conf" 2> find-errors.log | less
在 find /etc -name "*.conf" | less 中,如果没有其他重定向,find 的 stderr 通常去哪里?
使用 tee 复制数据流
如果您想同时在屏幕上查看输出并将其保存到文件中怎么办?这时 tee 命令就派上用场了。linux 中的 pipe and tee 命令 是用于日志记录和监控的经典组合。
$ ls | tee listing.txt
这里 listing.txt 会收到列表,tee 的 stdout 仍连接到终端。默认情况下,tee 会像 > 一样创建或清空指定文件。
哪个命令会显示 generate-report 的输出,同时用相同输出替换 report.txt?
需要追加文件而不是替换时,请使用 -a:
$ date | tee -a activity.log
哪个命令会显示当前日期,并把它追加到 activity.log?
保存中间结果
通过链接这些命令,您可以创建更高级的工作流程。一种常见模式是在较长的命令链中间使用 pipe to tee。这允许您在继续处理数据之前保存中间结果。
例如,您可以使用 linux pipe tee 组合来在进一步过滤之前查看和保存输出:
$ ls -la /etc | tee etc-listing.txt | grep "conf"
此命令执行三件事:
- 生成完整的长格式列表。
- 把完整数据流保存到
etc-listing.txt。 - 把相同数据流发送给
grep,由它只打印包含conf的行。
文件包含 grep 过滤前的数据。如果只想把筛选出的行写入文件,应把 tee 放在 grep 后面。
produce | tee all.txt | grep error 成功结束后,all.txt 包含什么?
要练习管道和数据流复制,可以尝试以下动手实验:
- 在 Linux 中重定向输入和输出 - 通过操作标准输出 (stdout)、标准错误 (stderr) 和标准输入 (stdin),并使用
>,>>,2>和tee命令等操作符,练习控制命令的数据流。 - 序列控制和管道 - 学习控制命令执行序列,利用管道,并利用强大的文本处理工具,如
cut、grep、wc、sort和uniq。 - 数据流重定向 - 学习 Linux 流重定向的艺术,包括操作标准输入、输出和错误流,组合输出以及利用
/dev/null。
课程已完成
你已完成 管道和 tee
现在,你可以连接命令,并保留数据流中的指定节点。
把一个命令的 stdout 通过管道送入另一个命令的 stdin。
按需单独重定向 stderr。
使用
tee把输入同时复制到文件和 stdout。使用
tee -a追加而不是替换文件。有意识地把
tee放在过滤器之前或之后。