6、管道和重定向
文件描述符:fd
概念
在Linux中一切皆文件,文件分为:普通文件、目录文件、连接文件和设备文件。
在操作这些文件时,每操作一次就要找一次名字,这会耗费大量的时间,所以Linux中规定每一个文件对应一个索引,这样要操作文件的时候,直接找到索引即可
文件描述符(file descriptor):fd,就是内核为了高效管理这些已经被打开的文件所创建的索引,是一个0~255的整数,用于指代被打开的文件,所有执行I/O操作的系统都通过文件描述符来实现。
其中0、1、2这三个fd被赋予特殊意义
- 0:标准输入(stdio)
- 1:标准正确输出(stdout)
- 2:标准错误输出(stderr)
所以我们打开的文件描述符从3开始,依次往后
查看文件的fd
-
使用vim打开文件:file,其路径为:
/root/rootdir/file
[root@localhost rootdir]# vim file
-
再另起一个终端,使用
ps
查看vim的进程号,可以看到是:14027[root@localhost rootdir]# ps axo pid,command | grep vim 14027 vim file
-
打开
/proc/14027/pf
路径。/proc是存放虚拟系统相关的文件,其中包括pf。14027是进程号,他使用进程号为目录名,里面存放该进程的相关信息。pf里面就是文件标识符
[root@localhost rootdir]# ls /proc/14027/fd 0 1 2 4
0、1、2、4是链接文件,相当于实际文件的快捷方式
-
使用
ls -l
查看详细信息[root@localhost rootdir]# ls -l /proc/14027/fd 总用量 0 lrwx------. 1 root root 64 4月 28 20:07 0 -> /dev/pts/3 lrwx------. 1 root root 64 4月 28 20:07 1 -> /dev/pts/3 lrwx------. 1 root root 64 4月 28 20:04 2 -> /dev/pts/3 lrwx------. 1 root root 64 4月 28 20:07 4 -> /root/rootdir/.file.swp
上面说了0、1、2、4是链接文件,文件的快捷方式,那么数字后面的 /dev/pts/3、/root/rootdir/.file.swp 就是快捷方式所指向的实际文件
注意:file.swp是vim创建的file的副本文件。具体前面有介绍
也就是说
cat 4
和cat /root/rootdir/file
的效果是一样的,将冗长的文件路径简化成了一个数字,极大的加快了操作文件的速度/dev/pts/3是我们的终端,也就是使用vim打开file文件的那个终端。可以在终端操作另一个终端,如下:
创建源文件的链接文件使用命令ln
,后面介绍
重定向
输出重定向
当我们敲我命令后,默认会将结果返回到当前终端进行显示
但是我们使用输出重定向后,返回的结果就不会在当前终端显示了,而是将结果放在重定向的位置,这个重定向的位置可以是:文件、其他终端等等
标准正确输出
使用符号:1>
和 1>>
。等价于:>
和 >>
。也就是将前面的标准正确输出标识符:1 给省略了
>:覆盖
使用 >
重定向到文件时,会覆盖文件中的内容
-
将命令:
ls -l
输出的正确结果放到文件:file中。并使用cat
命令查看是否放进去了[root@localhost rootdir]# ls -l > file [root@localhost rootdir]# cat file 总用量 4 drwxr-xr-x. 2 root root 6 4月 26 16:40 dir dr-xr-xr-x. 2 root root 6 4月 26 17:06 dir1 -rw-r--r--. 1 root root 0 4月 28 21:37 file -rwxr--r--. 1 root root 20 4月 28 09:14 ShFile.sh
-
再输入命令:
date
,将当前系统时间放到file文件中,并使用cat
命令查看[root@localhost rootdir]# date 1> file [root@localhost rootdir]# cat file 2024年 04月 28日 星期日 21:44:51 CST
可以观察到使用
>
或1>
重定向到文件时,会直接覆盖掉文件中原本的内容 -
我们输入错误的命令试一下
[root@localhost rootdir]# ls aaaaa > file ls: 无法访问aaaaa: 没有那个文件或目录 [root@localhost rootdir]# cat file [root@localhost rootdir]#
由于我们没有对标准错误输出进行重定向,所以默认显示在当前终端。
而且虽然该命令并没有产生标准正确输出,但是文件中的内容依然被覆盖了,也就是空
>>:追加
使用>>
重定向到文件时,直接在文件末尾进行追加,如下
// 第一次重定向
[root@localhost rootdir]# date >> file
[root@localhost rootdir]# cat file
2024年 04月 28日 星期日 21:52:05 CST
// 第二次重定向
[root@localhost rootdir]# date 1>> file
[root@localhost rootdir]# cat file
2024年 04月 28日 星期日 21:52:05 CST
2024年 04月 28日 星期日 21:52:17 CST
// 第三次重定向
[root@localhost rootdir]# date >> file
[root@localhost rootdir]# cat file
2024年 04月 28日 星期日 21:52:05 CST
2024年 04月 28日 星期日 21:52:17 CST
2024年 04月 28日 星期日 21:52:27 CST
标准错误输出
与标准正确输出差不多,只不过是将命令运行失败的结果输出出来
使用符号:2>
和 2>>
。不能简写
使用示例
将报错信息输出到文件:file中
-
2
:覆盖。[root@localhost rootdir]# data 2> file [root@localhost rootdir]# cat file bash: data: 未找到命令... [root@localhost rootdir]# lll 2> file [root@localhost rootdir]# cat file bash: lll: 未找到命令...
-
2>>
:追加。[root@localhost rootdir]# aaa 2>> file [root@localhost rootdir]# bbb 2>> file [root@localhost rootdir]# ccc 2>> file [root@localhost rootdir]# cat file bash: aaa: 未找到命令... bash: bbb: 未找到命令... bash: ccc: 未找到命令... 相似命令是: 'cc'
标准混合输出:&>和&>>
&>
:将标准正确输出和标准错误输出都输出到同一个文件中,以覆盖的形式
[root@localhost rootdir]# date &> file
[root@localhost rootdir]# cat file
2024年 04月 28日 星期日 22:22:57 CST
[root@localhost rootdir]# aaaaa &> file
[root@localhost rootdir]# cat file
bash: aaaaa: 未找到命令...
&>>
:将标准正确输出和标准错误输出都输出到同一个文件中,以追加的形式
[root@localhost rootdir]# date &>> file
[root@localhost rootdir]# llll &>> file
[root@localhost rootdir]# date &>> file
[root@localhost rootdir]# cat file
2024年 04月 29日 星期一 01:08:59 CST
bash: llll: 未找到命令...
2024年 04月 29日 星期一 01:09:10 CST
处理垃圾信息
当我们不想看见某个命令的运行结果或者不要的文件、信息等等,都可以输出到 /dev/null
文件中,这是专门用来处理垃圾信息的地方
[root@localhost rootdir]# ls -l &> /dev/null
将正确信息输出到yes.txt文件中,将错误信息,输出到no.txt文件中
[root@localhost rootdir]# lsssss -l 1>> yes.txt 2>> no.txt
[root@localhost rootdir]# ls -l 1>> yes.txt 2>> no.txt
[root@localhost rootdir]# cat yes.txt
总用量 12
drwxr-xr-x. 2 root root 6 4月 26 16:40 dir
dr-xr-xr-x. 2 root root 6 4月 26 17:06 dir1
-rw-r--r--. 1 root root 117 4月 29 01:09 file
-rw-r--r--. 1 root root 66 4月 29 01:17 no.txt
-rwxr--r--. 1 root root 20 4月 28 09:14 ShFile.sh
-rw-r--r--. 1 root root 0 4月 29 01:16 yes.txt
[root@localhost rootdir]# cat no.txt
bash: lsssss: 未找到命令...
输入重定向
符号:<
(等于与:0<
)和 <<
使用输入重定向发送邮件
[root@localhost rootdir]# cat file
第一行
第二行
第三行
第四行
[root@localhost rootdir]# mail -s "to user01" user01 < file
这样文件file中的内容就被当作邮件发送给用户user01了
管道
管道命令可以将多条命令组合起来,一次性处理复杂的任务
进程管道:|
将一个命令的正确输出当作另一个命令的输入
找到/etc/passwd 文件中包含有root字符串的行
[root@localhost rootdir]# cat /etc/passwd | grep root
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
tee管道:|tee
也可以叫三通管道
将一个命令的正确输出作为另一个命令的输入前,将该输出保存到文件或打印在终端上
将ps -aux
命令的正确输出保存到文件:file中,再作为命令grep vim
的输入
[root@localhost rootdir]# ps -aux |tee file | grep vim
root 4276 0.0 0.0 112824 976 pts/0 S+ 19:48 0:00 grep --color=auto vim
// 查看文件内容是否保存成功
[root@localhost rootdir]# cat file
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 128284 6948 ? Ss 16:50 0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0.0 0.0 0 0 ? S 16:50 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? S< 16:50 0:00 [kworker/0:0H]
root 6 0.0 0.0 0 0 ? S 16:50 0:00 [ksoftirqd/0]
root 7 0.0 0.0 0 0 ? S 16:50 0:00 [migration/0]
....省略了其他信息
管道参数:|xargs
有些命令需要的是文件参数,而不是文本输入,比如:ls、mv、cp、rm等等,这些命令都无法使用管道传递的文本输入
在路径/root/rootdir/ShFile.sh下有文件ShFile.sh,将该文件路径放到文件file中
[root@localhost rootdir]# cat file
/root/rootdir/ShFile.sh
此时,使用管道:| ,来查看文件file中文件路径的详细信息
[root@localhost rootdir]# cat file | ls -l
总用量 8
drwxr-xr-x. 2 root root 6 4月 26 16:40 dir
dr-xr-xr-x. 2 root root 6 4月 26 17:06 dir1
-rw-r--r--. 1 root root 24 4月 29 20:00 file
-rwxr--r--. 1 root root 47 4月 29 19:55 ShFile.sh
发现并不是我们预期中的结果,因为
cat file
命令返回的是文本信息,而ls -l
命令需要的是文件信息
在使用参数:|xargs,试一次
[root@localhost rootdir]# cat file |xargs ls -l
-rwxr--r--. 1 root root 47 4月 29 19:55 /root/rootdir/ShFile.sh
完美实现了我们预期的效果
删除文件也是同理
// 不是使用|xargs没有任何反应,因为rm需要的是文件信息
[root@localhost rootdir]# cat file | rm -rvf
// 使用 |xargs后成功删除
[root@localhost rootdir]# cat file |xargs rm -rvf
已删除"/root/rootdir/ShFile.sh"
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY