6、管道和重定向

文件描述符:fd

概念

在Linux中一切皆文件,文件分为:普通文件、目录文件、连接文件和设备文件。

在操作这些文件时,每操作一次就要找一次名字,这会耗费大量的时间,所以Linux中规定每一个文件对应一个索引,这样要操作文件的时候,直接找到索引即可

文件描述符(file descriptor):fd,就是内核为了高效管理这些已经被打开的文件所创建的索引,是一个0~255的整数,用于指代被打开的文件,所有执行I/O操作的系统都通过文件描述符来实现。

其中0、1、2这三个fd被赋予特殊意义

  • 0:标准输入(stdio)
  • 1:标准正确输出(stdout)
  • 2:标准错误输出(stderr)

所以我们打开的文件描述符从3开始,依次往后

查看文件的fd

  1. 使用vim打开文件:file,其路径为:/root/rootdir/file

    [root@localhost rootdir]# vim file
    
  2. 再另起一个终端,使用ps查看vim的进程号,可以看到是:14027

    [root@localhost rootdir]# ps axo pid,command | grep vim
     14027 vim file
    
  3. 打开/proc/14027/pf路径。

    /proc是存放虚拟系统相关的文件,其中包括pf。14027是进程号,他使用进程号为目录名,里面存放该进程的相关信息。pf里面就是文件标识符

    [root@localhost rootdir]# ls /proc/14027/fd
    0  1  2  4
    

    0、1、2、4是链接文件,相当于实际文件的快捷方式

  4. 使用ls -l查看详细信息

    [root@localhost rootdir]# ls -l  /proc/14027/fd
    总用量 0
    lrwx------. 1 root root 64 428 20:07 0 -> /dev/pts/3
    lrwx------. 1 root root 64 428 20:07 1 -> /dev/pts/3
    lrwx------. 1 root root 64 428 20:04 2 -> /dev/pts/3
    lrwx------. 1 root root 64 428 20:07 4 -> /root/rootdir/.file.swp
    

    上面说了0、1、2、4是链接文件,文件的快捷方式,那么数字后面的 /dev/pts/3、/root/rootdir/.file.swp 就是快捷方式所指向的实际文件

    注意:file.swp是vim创建的file的副本文件。具体前面有介绍

    也就是说cat 4cat /root/rootdir/file的效果是一样的,将冗长的文件路径简化成了一个数字,极大的加快了操作文件的速度

    /dev/pts/3是我们的终端,也就是使用vim打开file文件的那个终端。可以在终端操作另一个终端,如下:

创建源文件的链接文件使用命令ln,后面介绍

重定向

输出重定向

当我们敲我命令后,默认会将结果返回到当前终端进行显示

但是我们使用输出重定向后,返回的结果就不会在当前终端显示了,而是将结果放在重定向的位置,这个重定向的位置可以是:文件、其他终端等等

标准正确输出

使用符号:1>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 426 16:40 dir
    dr-xr-xr-x. 2 root root  6 426 17:06 dir1
    -rw-r--r--. 1 root root  0 428 21:37 file
    -rwxr--r--. 1 root root 20 428 09:14 ShFile.sh
    
  2. 再输入命令:date ,将当前系统时间放到file文件中,并使用cat命令查看

    [root@localhost rootdir]# date 1> file
    [root@localhost rootdir]# cat file
    20240428日 星期日 21:44:51 CST
    

    可以观察到使用 >1> 重定向到文件时,会直接覆盖掉文件中原本的内容

  3. 我们输入错误的命令试一下

    [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
20240428日 星期日 21:52:05 CST

// 第二次重定向
[root@localhost rootdir]# date 1>> file
[root@localhost rootdir]# cat file
20240428日 星期日 21:52:05 CST
20240428日 星期日 21:52:17 CST

// 第三次重定向
[root@localhost rootdir]# date >> file
[root@localhost rootdir]# cat file
20240428日 星期日 21:52:05 CST
20240428日 星期日 21:52:17 CST
20240428日 星期日 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
20240428日 星期日 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
20240429日 星期一 01:08:59 CST
bash: llll: 未找到命令...
20240429日 星期一 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 426 16:40 dir
dr-xr-xr-x. 2 root root   6 426 17:06 dir1
-rw-r--r--. 1 root root 117 429 01:09 file
-rw-r--r--. 1 root root  66 429 01:17 no.txt
-rwxr--r--. 1 root root  20 428 09:14 ShFile.sh
-rw-r--r--. 1 root root   0 429 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 426 16:40 dir
dr-xr-xr-x. 2 root root  6 426 17:06 dir1
-rw-r--r--. 1 root root 24 429 20:00 file
-rwxr--r--. 1 root root 47 429 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"
posted @   7七柒  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示