Linux 管道工作原理与使用
管道(|)是 Linux 命令行里超级好用的工具,它能让命令像流水线一样协作,把一个命令的输出直接传给另一个命令当输入。
基于 stdin、stdout 和 stderr 的知识,管道主要处理 stdout 和 stdin,让你轻松组合命令来完成复杂任务。
1. 什么是管道?
管道用 |
符号表示,它的作用是把左边命令的 stdout 直接送给右边命令的 stdin。简单说,就是让命令“串联”起来,像接水管一样,数据从一个命令流到下一个。
比如:
ls | grep "txt"
这里:
ls
的 stdout(当前目录的文件列表)通过管道传给grep
。grep "txt"
从 stdin 读取数据,过滤出包含 “txt” 的行。
结果是只显示文件名中包含 “txt” 的文件。
2. 管道的工作原理
管道的核心是把 stdout 和 stdin 连接起来。Linux 会:
- 运行左边的命令,把它的 stdout 临时存到一个内存缓冲区。
- 把这个缓冲区的内容作为右边命令的 stdin。
- 右边命令处理输入,输出结果(通常是 stdout,显示在终端)。
重要提醒:
- 管道只传 stdout,不传 stderr。stderr 默认还是显示在终端。
- 管道是单向的,数据从左到右流动。
试试这个:
ls /etc /notexist | grep "conf"
ls /etc /notexist
会输出/etc
的文件列表(stdout),同时在终端显示错误(stderr:ls: cannot access '/notexist': No such file or directory
)。grep "conf"
只从 stdin(即/etc
的文件列表)过滤出包含 “conf” 的行。
3. 基本用法:单个管道
单个管道是最简单的用法,把两个命令连起来:
echo "apple banana cherry" | tr 'a' 'A'
echo
输出 “apple banana cherry” 到 stdout。tr 'a' 'A'
从 stdin 读取,把小写a
替换成大写A
。
结果是:
Apple bAnAnA cherry
另一个例子:
cat file.txt | sort
如果 file.txt
包含几行文本,cat
把内容送到 stdout,sort
从 stdin 读取并按字母顺序排序后输出。
4. 多管道:串联多个命令
管道可以无限串联,组成复杂的处理链。比如:
ls /etc | grep "conf" | sort | head -n 2
这行命令:
ls /etc
列出/etc
目录的内容。grep "conf"
过滤出包含 “conf” 的行。sort
按字母顺序排序。head -n 2
只取前两行。
每个命令的 stdout 都成为下一个命令的 stdin,层层处理。
5. 管道与重定向结合
管道和重定向可以一起用,灵活处理输入输出。比如:
ls /etc | grep "conf" > output.txt
ls /etc | grep "conf"
:管道过滤出包含 “conf” 的文件。> output.txt
:把grep
的 stdout 写入output.txt
。
再来个复杂点的:
cat input.txt | grep "error" > output.txt 2> error.log
cat input.txt
的 stdout 送到grep
。grep "error"
过滤出包含 “error” 的行,输出到 stdout。> output.txt
把grep
的 stdout 存到output.txt
。2> error.log
把grep
的 stderr(如果有)存到error.log
。
6. 处理 stderr 在管道中
管道默认只传 stdout,stderr 不会进入管道。如果想让 stderr 也参与管道,需要先把 stderr 重定向到 stdout。用 2>&1
:
ls /etc /notexist 2>&1 | grep "conf"
2>&1
把 stderr 合并到 stdout。- 合并后的输出(stdout + stderr)通过管道送到
grep
。 grep "conf"
过滤包含 “conf” 的行(可能包括错误信息)。
试试看,输出可能包含错误信息(如果错误信息里带 “conf”)。
7. 使用 tee:在管道中保存中间结果
有时候你想在管道处理的同时,把中间结果存到文件,这可以用 tee
命令。tee
从 stdin 读取数据,同时写到文件和 stdout。
比如:
ls /etc | grep "conf" | tee conf_files.txt | sort
ls /etc | grep "conf"
:过滤出包含 “conf” 的文件。tee conf_files.txt
:把grep
的输出存到conf_files.txt
,同时继续传给下一个命令。sort
:对结果排序。
运行后,conf_files.txt
存了 grep
的输出,终端显示排序后的结果。
8. 常见管道命令组合
以下是一些超实用的管道组合:
- 统计行数:
cat file.txt | wc -l
wc -l
从 stdin 读取,统计行数。
- 查找并排序唯一项:
cat file.txt | sort | uniq
sort
排序,uniq
删除重复行。
- 过滤并计数:
dmesg | grep "error" | wc -l
统计内核日志(dmesg
)中包含 “error” 的行数。