博客原文链接Breeze在 Linux 的世界里一切皆文件是核心哲学。重定向和管道正是这一哲学的最佳体现——它们让命令之间能够自由沟通、协作将简单命令组合成强大的工作流。很多初学者觉得重定向和管道难以理解是因为没有搞清楚 Linux 是如何管理输入和输出的。本文将从最基础的文件描述符讲起逐步带你掌握输出重定向、输入重定向、管道、tee、xargs 等核心工具帮你打通 Linux 命令组合的任督二脉。请思考在深入重定向之前让我们先思考一个问题如何让命令的输出持久保存比如date命令输出的时间关机重启后还能查看吗答案当然是不能因为输出只是显示在屏幕上并没有保存下来解决办法使用重定向date date.txt把输出保存到文件中文件描述符 FD什么是文件描述符文件描述符File Descriptors简称 FD也叫文件句柄。进程使用文件描述符来管理打开的文件。举个简单例子说明想象你在图书馆借书图书馆操作系统有很多书文件你不能直接去书架上拿书而是需要通过借书卡文件描述符来获取书籍借书卡上的编号就是 FD通过这个编号你才能读取或写入文件标准输入、标准输出、标准错误每个 Linux 进程启动时系统会自动为它分配三个特殊的文件描述符FD 编号名称英文全称默认设备读写权限0标准输入Standard Input (stdin)键盘只读1标准输出Standard Output (stdout)屏幕只写2标准错误Standard Error (stderr)屏幕只写3其他文件-文件读写观察 FD 信息通过我们非常熟悉的 VIM 程序来观察一个进程的 FD 信息。步骤 1打开一个文本文件vim1.txt步骤 2在另一个终端查询 vim 的进程号psaux|grepvim输出示例root90690.10.51515325040pts/0 S 09:210:00vim1.txt步骤 3查看该进程的 FD 信息通常在 /proc/PID/fd 就能看到文件的FD调用情况。ls/proc/9069/fd普通的ls可能看不出什么加上-l参数试试ll /proc/9069/fd输出示例总用量0lrwx------.1root root645月1309:220-/dev/pts/0# 标准输入lrwx------.1root root645月1309:221-/dev/pts/0# 标准输出lrwx------.1root root645月1309:212-/dev/pts/0# 标准错误输出lrwx------.1root root645月1309:223-/root/.1.txt.swp# 常规文件vim 的交换文件分析0、1、2都指向/dev/pts/0终端设备3指向/root/.1.txt.swpvim 编辑文件时自动创建的临时交换文件总结看到的0、1、2、3就是文件描述符FD。程序通过描述符访问文件可以是常规文件也可以是设备文件。FD 就像是进程的借书卡通过它来读取或写入数据。输出重定向简介输出重定向就是把命令的输出结果从屏幕上转移到文件中。打个比方正常情况下命令的输出会显示在屏幕上标准输出。输出重定向就像给命令的输出换了个方向——不再显示在屏幕上而是写入到一个文件中。输出重定向的类型输出分为正确输出标准输出和错误输出标准错误类型完整写法简写说明示例正确输出 - 覆盖1覆盖写入如果文件已存在则清空后重新写入date date.txt正确输出 - 追加1追加写入在文件末尾添加内容date date.txt错误输出 - 覆盖2无简写仅将错误信息重定向到文件ls /aaa 2 error.txt错误输出 - 追加2无简写将错误信息追加到文件末尾ls /aaa 2 error.txt记忆技巧一个箭头表示覆盖就像新来的把原来的替换掉两个箭头表示追加新来的跟在后面案例 1正确输出重定向覆盖写入[rootlocalhost ~]# date 1 date.txt追加写入[rootlocalhost ~]# date date.txt检验效果[rootlocalhost ~]# cat date.txt2026年 05月13日 星期三 09:53:09 CST2026年 05月13日 星期三 09:54:42 CST# 再次覆盖写入[rootlocalhost ~]# date date.txt[rootlocalhost ~]# cat date.txt2026年 05月13日 星期三 09:55:12 CST注意任何程序都可以使用重定向比如mkdir -v /test mkdir.log只要程序本身有输出就可以重定向。案例 2错误输出重定向错误示范[rootlocalhost ~]# ls /home/ 2 list.txt打开list.txt会发现没有任何内容因为ls /home/是一个正确的命令没有产生错误信息。正确示范[rootlocalhost ~]# ls /aaaaaaaaa 2 list.txt[rootlocalhost ~]# cat list.txtls: 无法访问/aaaaaaaaa: 没有那个文件或目录关键点当某条命令产生错误时才会有错误输出。错误输出重定向就是把这些报错信息从屏幕上转移到文件中。案例 3正确和错误都输入到相同位置[rootlocalhost ~]# ls /home/ /aaaaaaaaa list.txt是 bash 的快捷写法等价于 file 21表示正确输出和错误输出都写入到同一个文件这里的1指的就是file这个文件这里做个了解就行。生产环境实战屏蔽所有输出[rootlocalhost ~]# yum install httpd /dev/null什么是/dev/null/dev/null是 Linux 系统中的一个特殊设备文件被称为黑洞。任何写入它的数据都会被丢弃读取它什么也得不到。当你不关心命令的输出时比如自动化脚本中可以把输出重定向到/dev/null避免产生大量日志文件。输入重定向简介输入重定向等价于0把一个文件的内容作为命令的输入代替手动键盘输入。打个比方正常使用邮箱发送邮件时你需要一行一行地输入邮件内容。如果已经有了现成的邮件内容文件输入重定向就像把文件内容喂给邮箱代替你手动输入。用cat命令读取文件cat命令的默认行为是从标准输入键盘读取内容并打印到屏幕。输入重定向可以让它从文件读取内容。步骤 1不用重定向从键盘输入cat运行后光标会停在终端你输入什么它就会立刻打印什么。按CtrlD结束输入。步骤2用输入重定向从文件读取# 先创建一个测试文件echo第一行内容test.txtecho第二行内容test.txtecho第三行内容test.txt# 输入重定向让cat从test.txt读取输入cattest.txt运行结果第一行内容 第二行内容 第三行内容原理 test.txt把标准输入fd 0从键盘重定向到文件test.txtcat命令本身没有任何变化它还是从 “标准输入” 读数据只是这个 “标准输入” 现在指向了文件管道管道|简介管道命令将多条命令组合起来一次性完成复杂的处理任务。语法command1|command2|command3|...形象理解管道就像一根水管命令 1 的输出 水龙头流出的水管道| 水管命令 2 的输入 水管另一端接收的水命令 1 的标准输出作为命令 2 的标准输入形成一个数据流转的链条。案例# 查看 /etc/passwd 文件的最后 3 行[rootlocalhost ~]# cat /etc/passwd | tail -3# 查找 sshd 相关的进程[rootlocalhost ~]# ps aux | grep sshd分步拆解第一步cat /etc/passwd作用把/etc/passwd这个文件的全部内容系统里所有用户的信息全部 “倒出来”第二步|管道作用把左边命令输出的所有内容原封不动地通过 “水管” 传给右边的命令第三步tail -3作用只接收水管流过来的内容然后只保留最后 3 行其他全部扔掉**最终效果**不用打开整个文件翻到最后一步直接看到系统用户文件的最后 3 行。第二个示例也是同理ps aux会静态显示所有进程通过管道符把所有进程交给grep后grep会筛选出于sshd相关的行作为结果输出tee 管道三通管道简介tee 管道三通管道即把数据交给另一个程序继续处理同时又保存一份副本到文件中。形象理解想象一个 T 形水管三通头水流数据从一端进入分成两路一路继续向前流交给下一个命令一路分流到侧面保存到文件案例[rootlocalhost ~]# cat /etc/passwd | tee 88.txt | tail -1jack:x:6674:6676::/home/jack:/bin/bash查看 tee 保存的文件内容[rootlocalhost ~]# cat 88.txt问题88.txt 文件中是什么内容一行还是所有行答案所有行因为 tee 保存的是命令 1cat处理的全部结果而tail -1只是从管道中取走的最后一行。参数传递 xargs为什么需要 xargs有些命令如cp、rm、mv比较特殊它们不接受管道的标准输入作为参数。打个比方管道就像传送带把上一个命令的输出传递给下一个命令。但rm、cp这些命令脾气倔不吃传送带上的东西只接受直接给它们的参数。xargs 就是翻译官把传送带上的内容翻译成这些命令能理解的参数格式。案例演示步骤 1环境准备创建一些文件[rootlocalhost ~]# touch /home/file{1..5}[rootlocalhost ~]# ls /homefile1 file2 file3 file4 file5步骤 2创建要删除的文件列表[rootlocalhost ~]# vim files.txt/home/file1 /home/file3 /home/file5步骤 3尝试直接用管道删除失败[rootlocalhost ~]# cat files.txt | rm -rvf# 查看/home下的文件发现删除失败rm 不会删除任何文件为什么会失败因为rm不接受管道的标准输入作为参数。它需要的是rm /home/file1 /home/file3 /home/file5这种参数形式。步骤 4加上 xargs 成功连接 rm 命令[rootlocalhost ~]# cat files.txt | xargs rm -rvf已删除/home/file1已删除/home/file3已删除/home/file5[rootlocalhost ~]# ls /homefile2 file4xargs 的作用原理# 没有 xargscatfiles.txt|rm-rvf# rm 收到的是标准输入但它看不懂# 有 xargscatfiles.txt|xargsrm-rvf# xargs 把文件内容转换成参数格式rm -rvf /home/file1 /home/file3 /home/file5xargs 常用用法# 查找所有 .log 文件并删除find/var/log-name*.log|xargsrm-f# 查找并统计行数find.-name*.txt|xargswc-l# 处理文件名中包含空格的情况使用 -d 指定分隔符find.-name*.txt-print0|xargs-0rm-f综合场景了解场景一日志分析# 查看访问日志中状态码为 404 的请求并统计数量cat/var/log/nginx/access.log|grep 404 |wc-l# 查看错误日志并保存到文件cat/var/log/nginx/error.log|tee/tmp/nginx_errors.txt|grepcritical场景二批量文件操作# 查找所有超过 100MB 的日志文件并删除find/var/log-name*.log-size100M|xargsrm-f# 查找所有 .conf 配置文件并备份find/etc-name*.conf|xargs-I{}cp{}{}.bak场景三自动化脚本中的输出管理# 安装软件包只保留错误输出yuminstall-ynginx/dev/null# 安装软件包将日志追加到文件yuminstall-ynginx/var/log/install.log21常见问题Q1和有什么区别操作符行为类比覆盖写入清空文件后再写入把黑板擦干净再写新内容追加写入在文件末尾添加在黑板内容的最后一行继续写Q221是什么意思21的含义是把标准错误FD 2重定向到标准输出FD 1当前指向的位置。# 正确输出和错误输出都写入到同一个文件commandoutput.log21# 或者使用 bash 快捷写法commandoutput.log注意顺序很重要command output.log 21和command 21 output.log的效果是不同的。Q3管道和重定向有什么区别| 特性 | 管道|| 重定向、||------|---------|----------------|| 连接对象 | 命令与命令 | 命令与文件 || 数据流向 | 命令1 的输出 → 命令2 的输入 | 命令的输出 → 文件或 文件的输入 → 命令 || 使用场景 | 组合多个命令处理数据 | 保存输出结果或读取文件内容 |Q4如何只保存正确输出忽略错误输出# 正确输出保存到文件错误输出丢弃到黑洞commandoutput.log2/dev/null最佳实践重定向前先确认文件是否存在会覆盖已有文件谨慎使用不确定时使用追加生产环境中合理管理输出不需要输出时用/dev/null避免产生无用日志需要追踪时用追加到日志文件管道命令链不要太长一般建议不超过 3-4 个管道连接太长可考虑写成 shell 脚本使用 xargs 处理大量文件时注意安全文件名含空格时使用-print0和-0参数删除前先用ls或echo预览善用 tee 同时查看和保存输出command|teeoutput.log|less总结通过本文的学习你应该掌握了理解文件描述符FD的概念和作用使用和进行正确输出重定向使用2和2进行错误输出重定向使用进行输入重定向使用|管道连接多个命令使用tee同时查看和保存输出使用xargs将标准输入转换为命令行参数学习建议重定向和管道是 Linux 命令行最强大的特性之一。建议在自己的虚拟机上多练习这些命令尝试将不同命令组合起来你会发现 Linux 命令行的无限可能