6.Linux 输入输出重定向(从零开始学)

📅 发布时间:2026/7/18 3:38:57
6.Linux 输入输出重定向(从零开始学) 1.Linux 输入输出重定向介绍上图显示了Unix/Linux 系统中进程PROCESS的输入输出流I/O Streams模型核心是 “标准流Standard Streams” 的概念用于描述进程如何与外部如键盘、屏幕、文件进行数据交互。1.1标准流的核心组成stdin标准输入编号 0是进程接收输入数据的通道默认连接到键盘程序通过它读取用户输入如scanf、read等操作会从stdin获取数据。用法为仅读取只能从该通道输入数据到进程。stdout标准输出编号 1是进程输出正常结果的通道默认连接到终端屏幕程序的普通打印如printf、echo等会输出到stdout。用法为仅写入进程只能向该通道输出数据。stderr标准错误编号 2是进程输出错误信息的通道默认也连接到终端屏幕用于区分正常输出和错误提示如程序崩溃、逻辑错误的提示信息。用法为仅写入专门用于输出错误内容。3 号通道其他文件filename代表进程与自定义文件的交互通道非标准流没有默认连接需要手动指定文件。用法为读取和 / 或写入可根据需求对文件进行读、写操作。1.2流程逻辑输入用户通过键盘向stdin输入数据进程从stdin读取这些输入。输出进程将正常结果写入stdout错误信息写入stderr两者默认都显示在终端同时进程也可通过 3 号通道与其他文件进行数据的读写交互。这种模型是 Unix/Linux 系统中 “一切皆文件” 思想的体现让进程能以统一的方式处理不同来源 / 目标的数据也为重定向Redirect等操作如把stdout输出到文件、把文件内容作为stdin输入提供了基础。2.标准输出重定向到文件# 查找 /etc 目录下 文件名是passwd的所有文件 [fengkaifengkai ~ 18:59:23]$ find /etc -name passwd find: ‘/etc/grub.d’: 权限不够 find: ‘/etc/pki/CA/private’: 权限不够 find: ‘/etc/pki/rsyslog’: 权限不够 /etc/pam.d/passwd find: ‘/etc/dhcp’: 权限不够 /etc/passwd find: ‘/etc/selinux/targeted/active’: 权限不够 ....... # 将找到的文件名清单覆盖写入到passwd.list文件中 [fengkaifengkai ~ 18:59:41]$ find /etc -name passwd 1passwd.list find: ‘/etc/grub.d’: 权限不够 find: ‘/etc/pki/CA/private’: 权限不够 find: ‘/etc/pki/rsyslog’: 权限不够 find: ‘/etc/dhcp’: 权限不够 ...... [fengkaifengkai ~ 19:00:36]$ cat passwd.list /etc/pam.d/passwd /etc/passwd # 补充说明 # 1passwd.list可简写为passwd.list # 1和之间不能有空格 # 将多个文件内容合并为1个分别查看各个文件的确是内容加在一起了 [fengkaifengkai ~ 19:00:47]$ cat /etc/fstab /etc/hosts allinone [fengkaifengkai ~ 19:01:56]$ cat allinone # # /etc/fstab # Created by anaconda on Tue Jul 14 10:25:59 2026 # # Accessible filesystems, by reference, are maintained under /dev/disk # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/centos-root / xfs defaults 0 0 UUIDcf271b57-4d0f-4dc8-954a-92dc152a1304 /boot xfs defaults 0 0 /dev/mapper/centos-home /home xfs defaults 0 0 /dev/mapper/centos-swap swap swap defaults 0 0 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 [fengkaifengkai ~ 19:02:23]$ cat /etc/fstab # # /etc/fstab # Created by anaconda on Tue Jul 14 10:25:59 2026 # # Accessible filesystems, by reference, are maintained under /dev/disk # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/centos-root / xfs defaults 0 0 UUIDcf271b57-4d0f-4dc8-954a-92dc152a1304 /boot xfs defaults 0 0 /dev/mapper/centos-home /home xfs defaults 0 0 /dev/mapper/centos-swap swap swap defaults 0 0 [fengkaifengkai ~ 19:02:39]$ cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 # 将找到的文件名清单追加写入到passwd.list文件中 [fengkaifengkai ~ 19:02:47]$ find /etc -name passwd 1passwd.list find: ‘/etc/grub.d’: 权限不够 find: ‘/etc/pki/CA/private’: 权限不够 find: ‘/etc/pki/rsyslog’: 权限不够 find: ‘/etc/dhcp’: 权限不够 ...... [fengkaifengkai ~ 19:05:30]$ cat passwd.list /etc/pam.d/passwd /etc/passwd /etc/pam.d/passwd /etc/passwd # 将错误信息覆盖写入到passwd.err文件中 [fengkaifengkai ~ 19:05:36]$ find /etc -name passwd 2passwd.err /etc/pam.d/passwd /etc/passwd [fengkaifengkai ~ 19:06:36]$ cat passwd.err find: ‘/etc/grub.d’: 权限不够 find: ‘/etc/pki/CA/private’: 权限不够 find: ‘/etc/pki/rsyslog’: 权限不够 find: ‘/etc/dhcp’: 权限不够 ...... # 将错误信息扔掉 [fengkaifengkai ~ 19:06:45]$ find /etc -name passwd 2/dev/null /etc/pam.d/passwd /etc/passwd # 将错误信息追加写入到passwd.err文件中 [fengkaifengkai ~ 19:07:17]$ find /etc -name passwd 2passwd.err /etc/pam.d/passwd /etc/passwd [fengkaifengkai ~ 19:07:52]$ cat passwd.err find: ‘/etc/grub.d’: 权限不够 find: ‘/etc/pki/CA/private’: 权限不够 find: ‘/etc/pki/rsyslog’: 权限不够 find: ‘/etc/dhcp’: 权限不够 find: ‘/etc/selinux/targeted/active’: 权限不够 find: ‘/etc/selinux/final’: 权限不够 find: ‘/etc/lvm/archive’: 权限不够 find: ‘/etc/lvm/backup’: 权限不够 find: ‘/etc/lvm/cache’: 权限不够 ...... # 将错误信息、正确信息 覆盖 写入到不同文件 [fengkaifengkai ~ 19:08:29]$ find /etc -name passwd passwd.list 2passwd.err # 将错误信息、正确信息 追加 写入到不同文件 [fengkaifengkai ~ 19:09:26]$ find /etc -name passwd passwd.list 2passwd.err # 用于清空文件内容也可用于创建一个空文件testfile [fengkaifengkai ~ 19:10:00]$ test [fengkaifengkai ~ 19:10:05]$ vi test [fengkaifengkai ~ 19:10:59]$ head test hello # 如果不存在则创建一个文件如果文件存在则啥也不干。 [fengkaifengkai ~ 19:11:03]$ test [fengkaifengkai ~ 19:11:16]$ head test hello# 同时将错误信息、正确信息 覆盖 写入到相同文件 [fengkaifengkai ~ 19:11:19]$ find /etc -name passwd passwd.all [fengkaifengkai ~ 19:12:53]$ cat passwd.all find: ‘/etc/grub.d’: 权限不够 find: ‘/etc/pki/CA/private’: 权限不够 find: ‘/etc/pki/rsyslog’: 权限不够 /etc/pam.d/passwd find: ‘/etc/dhcp’: 权限不够 /etc/passwd ····· # 同时将错误信息、正确信息 追加 写入到相同文件 [fengkaifengkai ~ 19:13:02]$ find /etc -name passwd passwd.all [fengkaifengkai ~ 19:13:25]$ cat passwd.all find: ‘/etc/grub.d’: 权限不够 find: ‘/etc/pki/CA/private’: 权限不够 find: ‘/etc/pki/rsyslog’: 权限不够 /etc/pam.d/passwd find: ‘/etc/dhcp’: 权限不够 /etc/passwd find: ‘/etc/selinux/targeted/active’: 权限不够 ·····3.标准输出重定向到程序管道符|实现将上一个命令的输出作为标准输入传递给下一个命令。# 示例1 查看哪个man page 可以resize ext4文件系统大小 # 搜索所有ext4相关手册并保存到ext4.man文件中 [fengkaifengkai ~ 19:13:27]$ man -k ext4 ext4.man [fengkaifengkai ~ 19:14:25]$ cat ext4.man debugfs (8) - ext2/ext3/ext4 file system debugger dumpe2fs (8) - dump ext2/ext3/ext4 filesystem information e2fsck (8) - check a Linux ext2/ext3/ext4 file system e2image (8) - Save critical ext2/ext3/ext4 filesystem metadata to a file e2label (8) - Change the label on an ext2/ext3/ext4 filesystem e2undo (8) - Replay an undo log for an ext2/ext3/ext4 filesystem e4defrag (8) - online defragmenter for ext4 filesystem ext4 (5) - the fourth extended file system ····· # 过滤ext4.man文件中含有resize的行 [fengkaifengkai ~ 19:14:28]$ grep resizer ext4.man resize2fs (8) - ext2/ext3/ext4 file system resizer # 以上两个命令和合并为一行 [fengkaifengkai ~ 19:15:00]$ man -k ext4 | grep resizer resize2fs (8) - ext2/ext3/ext4 file system resizer # 示例2 获取ens33网卡ip地址 [fengkaifengkai ~ 19:15:15]$ ip addr | grep ens33$ | awk {print $2}|cut -d/ -f1 10.1.8.10注意管道符号后的命令必须能够接收标准输入例如ls不接收管道传递过来的标准输入。[fengkaifengkai ~ 19:15:31]$ echo /etc/passwd | ls -l 总用量 28 -rw-rw-r--. 1 fengkai fengkai 699 7月 16 19:01 allinone -rw-r--r--. 1 fengkai fengkai 367 7月 16 18:44 dhcpd.conf -rw-rw-r--. 1 fengkai fengkai 1294 7月 16 19:14 ext4.man -rw-rw-r--. 1 fengkai fengkai 1594 7月 16 19:13 passwd.all -rw-rw-r--. 1 fengkai fengkai 1534 7月 16 19:09 passwd.err -rw-rw-r--. 1 fengkai fengkai 60 7月 16 19:09 passwd.list -rw-rw-r--. 1 fengkai fengkai 6 7月 16 19:10 test drwxr-xr-x. 2 fengkai fengkai 6 7月 14 10:39 公共 drwxr-xr-x. 2 fengkai fengkai 6 7月 14 10:39 模板 drwxr-xr-x. 2 fengkai fengkai 6 7月 14 10:39 视频 drwxr-xr-x. 2 fengkai fengkai 6 7月 14 10:39 图片 drwxr-xr-x. 2 fengkai fengkai 6 7月 14 10:39 文档 drwxr-xr-x. 2 fengkai fengkai 6 7月 14 10:39 下载 drwxr-xr-x. 2 fengkai fengkai 6 7月 14 10:39 音乐 drwxr-xr-x. 2 fengkai fengkai 25 7月 14 11:08 桌面补充| 标准错误和标准输出同时传递给下一个命令作为下一个命令的标准输入。[fengkaifengkai ~ 19:18:55]$ touch file-{01..03} [fengkaifengkai ~ 19:19:08]$ ls allinone ext4.man file-02 passwd.all passwd.list 公共 视频 文档 音乐 dhcpd.conf file-01 file-03 passwd.err test 模板 图片 下载 桌面 [fengkaifengkai ~ 19:19:09]$ ls -l file-{01..06} ls: 无法访问file-04: 没有那个文件或目录 ls: 无法访问file-05: 没有那个文件或目录 ls: 无法访问file-06: 没有那个文件或目录 -rw-rw-r--. 1 fengkai fengkai 0 7月 16 19:19 file-01 -rw-rw-r--. 1 fengkai fengkai 0 7月 16 19:19 file-02 -rw-rw-r--. 1 fengkai fengkai 0 7月 16 19:19 file-03 [fengkaifengkai ~ 19:19:51]$ ls -l file-{01..06} | grep file-06 ls: 无法访问file-04: 没有那个文件或目录 ls: 无法访问file-05: 没有那个文件或目录 ls: 无法访问file-06: 没有那个文件或目录 [fengkaifengkai ~ 19:20:22]$ ls -l file-{01..06} | grep file-03 ls: 无法访问file-04: 没有那个文件或目录 ls: 无法访问file-05: 没有那个文件或目录 ls: 无法访问file-06: 没有那个文件或目录 -rw-rw-r--. 1 fengkai fengkai 0 7月 16 19:19 file-03 # | [fengkaifengkai ~ 19:20:43]$ ls -l file-{01..06} | grep file-06 ls: 无法访问file-06: 没有那个文件或目录4.tee 命令tee 命令作用接收管道传递过来的stdin并继续作为stdout输出。[fengkaifengkai ~ 19:23:20]$ passwd.list [fengkaifengkai ~ 19:23:46]$ cat passwd.list [fengkaifengkai ~ 19:23:52]$ # tee命令覆盖保存到文件 [fengkaifengkai ~ 19:24:14]$ find /etc -name passwd 2/dev/null | tee passwd.list /etc/pam.d/passwd /etc/passwd [fengkaifengkai ~ 19:24:47]$ cat passwd.list /etc/pam.d/passwd /etc/passwd # tee命令追加保存到文件 [fengkaifengkai ~ 19:25:29]$ find /etc -name passwd 2/dev/null | tee -a passwd.list /etc/pam.d/passwd /etc/passwd [fengkaifengkai ~ 19:25:50]$ cat passwd.list /etc/pam.d/passwd /etc/passwd /etc/pam.d/passwd /etc/passwd # tee的标准输出继续通过管道传递下去 [fengkaifengkai ~ 19:25:52]$ man -k passwd | tee passwd.man | grep passwd chgpasswd (8) - 批量更新组密码 chpasswd (8) - 批量更新密码 ····· saslpasswd2 (8) - set a users sasl password vncpasswd (1) - change the VNC password [fengkaifengkai ~ 19:26:22]$ cat passwd.man chgpasswd (8) - 批量更新组密码 chpasswd (8) - 批量更新密码 ····· saslpasswd2 (8) - set a users sasl password vncpasswd (1) - change the VNC password5.标准输入重定向给程序# 常规查看文件 [fengkaifengkai ~ 19:29:51]$ cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 # cat 命令标准输入数据 [fengkaifengkai ~ 19:29:56]$ cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 [fengkaifengkai ~ 19:29:58]$ cat回车 hello # 键盘输入hello后回车 hello # 屏幕上显示hello ctrld # 输入完成退出 # shell读取到EOF时候代表标准输入完成 [fengkaifengkai ~ 19:32:16]$ cat EOF hello world eof EOF hello world eof # 使用直接输出 [fengkaifengkai ~ 19:33:19]$ cat hello world hello world判定一个命令是否接收标准输入最简单的方式就是将文件内容作为标准输入重定向给程序。思考如何一次性将多行内容写入到文件中# 方法1使用引号 [fengkaifengkai ~ 19:35:12]$ echo hello world hello linux multi_lines.txt [fengkaifengkai ~ 19:35:53]$ cat multi_lines.txt hello world hello linux # 方法2使用cat重定向 [fengkaifengkai ~ 19:35:59]$ cat multi_lines.txt EOF 1 2 3 EOF [fengkaifengkai ~ 19:37:13]$ cat multi_lines.txt 1 2 36.综合测试(无标准答案看自己理解以下为我的理解)1.你对谈谈你对输出重定向的理解用示例说明。正常敲完命令之后如find /etc -name passwd屏幕之上有回显有正确的1和错误的2我们可以将这些进行分类处理将正确的通过find /etc -name passwd 1xxx.txt收集到xxx.txt中将错误的通过find /etc -name passwd 2yyy.txt收集到yyy.txt中。每执行过一次就会覆盖可以通过就会持续收集。2.谈谈你对管道符|的理解用示例说明。通过对当前命令的输出信息进行二次的匹配筛选获取想要的数据可以多次使用直到匹配出你想要的结果。[fengkaifengkai ~ 19:15:15]$ ip addr | grep ens33$ | awk {print $2}|cut -d/ -f110.1.8.103.谈谈你对tee命令的理解用示例说明。配合|符使用将当前显示的数据存储到相应的文件中find /etc -name passwd 2/dev/null | tee passwd.list 为了防止覆盖可以加-afind /etc -name passwd 2/dev/null | tee -a passwd.list4.谈谈你对标准输入重定向的理解用示例说明。将文件内容重新输入给程序如 cat /etc/hosts或者直接输出如 cat hello world配合将内容写入到文件中如 cat multi_lines.txt EOF