云计算基础-5:Linux 重定向与管道
2026/6/15 13:11:58 网站建设 项目流程

📌 博客原文链接:Breeze

在 Linux 的世界里,"一切皆文件"是核心哲学。重定向和管道正是这一哲学的最佳体现——它们让命令之间能够自由沟通、协作,将简单命令组合成强大的工作流。

很多初学者觉得重定向和管道难以理解,是因为没有搞清楚 Linux 是如何管理"输入"和"输出"的。本文将从最基础的文件描述符讲起,逐步带你掌握输出重定向、输入重定向、管道、tee、xargs 等核心工具,帮你打通 Linux 命令组合的任督二脉。


请思考

在深入重定向之前,让我们先思考一个问题:

如何让命令的输出持久保存?


文件描述符 FD

什么是文件描述符?

文件描述符(File Descriptors,简称 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 root6451309:220->/dev/pts/0# 标准输入lrwx------.1root root6451309:221->/dev/pts/0# 标准输出lrwx------.1root root6451309:212->/dev/pts/0# 标准错误输出lrwx------.1root root6451309:223->/root/.1.txt.swp# 常规文件(vim 的交换文件)

分析:

总结:看到的0123就是文件描述符(FD)。程序通过描述符访问文件,可以是常规文件,也可以是设备文件。FD 就像是进程的"借书卡",通过它来读取或写入数据。


输出重定向

简介

输出重定向就是把命令的输出结果从屏幕上转移到文件中

打个比方:

正常情况下,命令的输出会"显示"在屏幕上(标准输出)。输出重定向就像给命令的输出换了个方向——不再显示在屏幕上,而是"写入"到一个文件中。

输出重定向的类型

输出分为正确输出(标准输出)错误输出(标准错误)

类型完整写法简写说明示例
正确输出 - 覆盖1>>覆盖写入,如果文件已存在则清空后重新写入date > date.txt
正确输出 - 追加1>>>>追加写入,在文件末尾添加内容date >> date.txt
错误输出 - 覆盖2>无简写仅将错误信息重定向到文件ls /aaa 2> error.txt
错误输出 - 追加2>>无简写将错误信息追加到文件末尾ls /aaa 2>> error.txt

记忆技巧

案例 1:正确输出重定向

覆盖写入:

[root@localhost ~]# date 1> date.txt

追加写入:

[root@localhost ~]# date >> date.txt

检验效果:

[root@localhost ~]# cat date.txt2026年 05月13日 星期三 09:53:09 CST2026年 05月13日 星期三 09:54:42 CST
# 再次覆盖写入[root@localhost ~]# date > date.txt[root@localhost ~]# cat date.txt2026年 05月13日 星期三 09:55:12 CST

注意:任何程序都可以使用重定向!比如mkdir -v /test > mkdir.log,只要程序本身有输出,就可以重定向。

案例 2:错误输出重定向

错误示范:

[root@localhost ~]# ls /home/ 2> list.txt

打开list.txt会发现没有任何内容,因为ls /home/是一个正确的命令,没有产生错误信息。

正确示范:

[root@localhost ~]# ls /aaaaaaaaa 2> list.txt[root@localhost ~]# cat list.txtls: 无法访问/aaaaaaaaa: 没有那个文件或目录

关键点:当某条命令产生错误时,才会有错误输出。错误输出重定向就是把这些"报错信息"从屏幕上转移到文件中。

案例 3:正确和错误都输入到相同位置

[root@localhost ~]# ls /home/ /aaaaaaaaa &> list.txt

&>是 bash 的快捷写法,等价于> file 2>&1,表示正确输出和错误输出都写入到同一个文件(这里的&1指的就是file这个文件,这里做个了解就行)。

生产环境实战:屏蔽所有输出

[root@localhost ~]# yum install httpd &>/dev/null

什么是/dev/null

/dev/null是 Linux 系统中的一个特殊设备文件,被称为黑洞。任何写入它的数据都会被丢弃,读取它什么也得不到。

当你不关心命令的输出时(比如自动化脚本中),可以把输出重定向到/dev/null,避免产生大量日志文件。


输入重定向

简介

输入重定向<(等价于0<:把一个文件的内容作为命令的输入,代替手动键盘输入。

打个比方:

正常使用邮箱发送邮件时,你需要一行一行地输入邮件内容。如果已经有了现成的邮件内容文件,输入重定向就像"把文件内容喂给邮箱",代替你手动输入。

cat命令读取文件

cat命令的默认行为是从标准输入(键盘)读取内容并打印到屏幕。输入重定向可以让它从文件读取内容。

步骤 1:不用重定向(从键盘输入)

cat

运行后光标会停在终端,你输入什么,它就会立刻打印什么。按Ctrl+D结束输入。

步骤2:用输入重定向(从文件读取)

# 先创建一个测试文件echo"第一行内容">test.txtecho"第二行内容">>test.txtecho"第三行内容">>test.txt# 输入重定向:让cat从test.txt读取输入cat<test.txt

运行结果:

第一行内容 第二行内容 第三行内容

原理


管道

管道|

简介

管道命令:将多条命令组合起来,一次性完成复杂的处理任务。

语法:

command1|command2|command3|...

形象理解:

管道就像一根水管:

命令 1 的标准输出作为命令 2 的标准输入,形成一个数据流转的链条。

案例

# 查看 /etc/passwd 文件的最后 3 行[root@localhost ~]# cat /etc/passwd | tail -3# 查找 sshd 相关的进程[root@localhost ~]# ps aux | grep 'sshd'

分步拆解:

  1. 第一步:cat /etc/passwd
    • 作用:把/etc/passwd这个文件的全部内容(系统里所有用户的信息)全部 “倒出来”
  2. 第二步:|(管道)
    • 作用:把左边命令输出的所有内容,原封不动地通过 “水管” 传给右边的命令
  3. 第三步:tail -3
    • 作用:只接收水管流过来的内容,然后只保留最后 3 行,其他全部扔掉

**最终效果:**不用打开整个文件翻到最后,一步直接看到系统用户文件的最后 3 行。

第二个示例也是同理,ps aux会静态显示所有进程,通过管道符把所有进程交给grep后,grep会筛选出于sshd相关的行作为结果输出


tee 管道(三通管道)

简介

tee 管道:三通管道,即把数据交给另一个程序继续处理,同时又保存一份副本到文件中。

形象理解:

想象一个 T 形水管三通头:

案例

[root@localhost ~]# cat /etc/passwd | tee 88.txt | tail -1jack:x:6674:6676::/home/jack:/bin/bash

查看 tee 保存的文件内容:

[root@localhost ~]# cat 88.txt

问题:88.txt 文件中是什么内容?一行还是所有行?

答案:所有行!因为 tee 保存的是命令 1(cat)处理的全部结果,而tail -1只是从管道中取走的最后一行。


参数传递 xargs

为什么需要 xargs?

有些命令(如cprmmv)比较特殊,它们不接受管道的标准输入作为参数

打个比方:

管道就像传送带,把上一个命令的输出传递给下一个命令。但rmcp这些命令"脾气倔",不吃传送带上的东西,只接受直接给它们的参数。

xargs 就是翻译官,把传送带上的内容"翻译"成这些命令能理解的参数格式。

案例演示

步骤 1:环境准备,创建一些文件

[root@localhost ~]# touch /home/file{1..5}[root@localhost ~]# ls /homefile1 file2 file3 file4 file5

步骤 2:创建要删除的文件列表

[root@localhost ~]# vim files.txt/home/file1 /home/file3 /home/file5

步骤 3:尝试直接用管道删除(失败)

[root@localhost ~]# cat files.txt | rm -rvf# 查看/home下的文件,发现删除失败!rm 不会删除任何文件

为什么会失败?因为rm不接受管道的标准输入作为参数。它需要的是rm /home/file1 /home/file3 /home/file5这种参数形式。

步骤 4:加上 xargs 成功连接 rm 命令

[root@localhost ~]# cat files.txt | xargs rm -rvf已删除"/home/file1"已删除"/home/file3"已删除"/home/file5"[root@localhost ~]# ls /homefile2 file4

xargs 的作用原理:

# 没有 xargs:catfiles.txt|rm-rvf# rm 收到的是标准输入,但它看不懂# 有 xargs:catfiles.txt|xargsrm-rvf# xargs 把文件内容转换成参数格式:rm -rvf /home/file1 /home/file3 /home/file5

xargs 常用用法

# 查找所有 .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|grep"critical"

场景二:批量文件操作

# 查找所有超过 100MB 的日志文件并删除find/var/log-name"*.log"-size+100M|xargsrm-f# 查找所有 .conf 配置文件并备份find/etc-name"*.conf"|xargs-I{}cp{}{}.bak

场景三:自动化脚本中的输出管理

# 安装软件包,只保留错误输出yuminstall-ynginx&>/dev/null# 安装软件包,将日志追加到文件yuminstall-ynginx>>/var/log/install.log2>&1

常见问题

Q1:>>>有什么区别?

操作符行为类比
>覆盖写入,清空文件后再写入把黑板擦干净再写新内容
>>追加写入,在文件末尾添加在黑板内容的最后一行继续写

Q2:2>&1是什么意思?

2>&1的含义是:把标准错误(FD 2)重定向到标准输出(FD 1)当前指向的位置

# 正确输出和错误输出都写入到同一个文件command>output.log2>&1# 或者使用 bash 快捷写法command&>output.log

注意:顺序很重要!command > output.log 2>&1command 2>&1 > output.log的效果是不同的。

Q3:管道和重定向有什么区别?

| 特性 | 管道|| 重定向><|
|------|---------|----------------|
| 连接对象 | 命令与命令 | 命令与文件 |
| 数据流向 | 命令1 的输出 → 命令2 的输入 | 命令的输出 → 文件,或 文件的输入 → 命令 |
| 使用场景 | 组合多个命令处理数据 | 保存输出结果或读取文件内容 |

Q4:如何只保存正确输出,忽略错误输出?

# 正确输出保存到文件,错误输出丢弃到黑洞command>output.log2>/dev/null

最佳实践

  1. 重定向前先确认文件是否存在

  2. 生产环境中合理管理输出

  3. 管道命令链不要太长

  4. 使用 xargs 处理大量文件时注意安全

  5. 善用 tee 同时查看和保存输出

    command|teeoutput.log|less

总结

通过本文的学习,你应该掌握了:

学习建议:重定向和管道是 Linux 命令行最强大的特性之一。建议在自己的虚拟机上多练习这些命令,尝试将不同命令组合起来,你会发现 Linux 命令行的无限可能!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询