I/O重定向管道

发布时间 2023-11-15 23:42:53作者: 辞瑾

一、I/O重定向

1.案例分析

(1)date命令:用于显示和设置系统当前的日期和时间

         date >命令:将date的输出结果重定向到一个普通文件

         参数设置:

-d<字符串>:显示字符串所指的日期与时间,字符串前后必须加上双引号。
-s<字符串>:根据字符串来设置日期与时间,字符串前后必须加上双引号。
-U:显示GMT.
--help:在线帮助。
--version:显示date版本信息。

[root@localhost ~]# tty
/dev/pts/0
[root@localhost ~]# date >/dev/pts/1
[root@localhost ~]# date > /dev/pts/0
2023年 11月 07日 星期二 22:40:20 CST
                      



[root@localhost ~]# tty
/dev/pts/1
[root@localhost ~]# 2023年 11月 07日 星期二 22:39:52 CST
示例

 

(2)大多数进程中,都包含文件描述符:0、1、2。

0:表示标准输入,可理解为键盘输入

1:表示标准输出,输出到终端

2:表示标准错误,输出到终端

3及以上则为常规文件描述符

文件描述符 通道名 说明 默认连接 用法
0 stdin 标准输入 键盘 只读
1 stdout 标准输出 终端 只写
2 stderr 标准错误 终端 只写
3+ filename 其他文件 可读可写/只读/只写

 

 

 (3)重定向概念:例如,date命令在默认情况下将输出结果显示在终端,此时文件描述符为1。若改变输出的方向,从终端改为date.txt文件,则这个行为称为“重定向”。

[root@localhost ~]# date 1> date.txt
示例
[root@localhost ~]# date 2>date.txt
2023年 11月 07日 星期二 23:03:10 CST

改变描述符为2的文件的输出方向,date命令是正确的,执行结果在终端显示
示例

 

(4)cat命令默认文件描述符为0,输入重定向把键盘输入改为/etc/hosts文件输入。

[root@localhost ~]# cat
linyx
linyx
qfedu
qfedu
[root@localhost ~]# cat 0< /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
示例

2.输出重定向

(1)输出重定向是一种在命令行中修改输出内容位置的技术。简单来说,它改变了通常会在屏幕上显示的结果的位置,而是将结果保存到指定的文件中。这种重定向对于保存程序的输出、忽略某些命令的警告或错误信息、分别保存正确和错误的输出信息等情况非常有用。

(2)在输出重定向操作中,可以使用">”和">>”两种符号进行操作。

">” 符号:表示将标准输出的内容写到后面的文件中,如果文件已存在,则会覆盖源文件中的内容

>>”符号:表示将标准输出的内容追加到后面的文件中,如果文件不存在,则会新建该文件。

例如,"Is /etc/passwd xxx > a.txt"这条命令表示将"Is /etc/passwd xxx”命令的输出结果保存到a.txt这个文件中,如果a.txt这个文件已经存在,那么这个命令会覆盖掉文件中原有的内容。

[root@localhost ~]# date > date.txt
[root@localhost ~]# date > date.txt
[root@localhost ~]# date > date.txt
[root@localhost ~]# cat date.txt
2023年 11月 15日 星期三 22:10:49 CST
[root@localhost ~]# date >> date.txt
[root@localhost ~]# date >> date.txt
[root@localhost ~]# date >> date.txt
[root@localhost ~]# cat date.txt
2023年 11月 15日 星期三 22:10:49 CST
2023年 11月 15日 星期三 22:11:05 CST
2023年 11月 15日 星期三 22:11:07 CST
2023年 11月 15日 星期三 22:11:09 CST
> 和 >>

(3)正确结果和错误结果都输出到相同位置

[root@localhost ~]# ls /home/ /linux &>list.txt
示例

(4)正确结果和错误结果都输出重定向到相同位置

[root@localhost ~]# ls /home/ /linux > list.txt 2>&1
示例

 

3.输入重定向

(1)输入重定向是一种在命令行中修改输入内容来源的技术。它改变了通常会从键盘获取输入的方式,而是将输入从指定的文件或命令中获取。这种重定向对于批量处理数据、从文件中读取输入、或者将命令的输出作为另一个命令的输入等情况非常有用。
(2)在输入重定向操作中,可以使用"<"符号进行操作。这个符号表示将后面的文件作为命令的输入,而不是从键盘获取输入。例如,"sort < file.txt" 这条命令表示将file.txt文件的内容作为sort命令的输入,而不是从键盘输入。

(3)实例:使用dd命令从dev/zero中读取文件并写入到file01.txt文件,每次写入1MiB,一共写入2次;使用输入重定向与输出重定向的方式也可以实现同样的功能。

 

[root@localhost ~]# dd if=/dev/zero of=file01.txt bs=1M count=2
记录了2+0 的读入
记录了2+0 的写出
2097152字节(2.1 MB)已复制,0.00442757 秒,474 MB/秒
[root@localhost ~]# dd </dev/zero>file2.txt bs=1M count=2
记录了2+0 的读入
记录了2+0 的写出
2097152字节(2.1 MB)已复制,0.00117291 秒,1.8 GB/秒
示例

 

(4)实例:使用at命令创建一个计划任务,从现在开始5分钟后创建用户linux,按组合键Ctrl+d结束;若同时创建多个用户,使用输入重定向则会非常方便。

[root@localhost ~]# at now +5 min
at> useradd linux
at> <EOF>
at> <EOF><EOT>
job 2 at Wed Nov 15 23:35:00 2023
[root@localhost ~]# vim use.txt
[root@localhost ~]# cat use.txt
useradd linux01
useradd linux02
useradd linux03
[root@localhost ~]# at now +5 min < use.txt
job 3 at Wed Nov 15 23:38:00 2023
示例

 

 

 

二、进程管道

(1)Linux的进程管道是一种用于进程间通信 (IPC) 的机制,它允许两个进程之间通过文件读写的方式单向传递数据。管道是半双工的,即数据只能在两个方向之一上传输,同一时间只允许一个进程发送或接收数据。

(2)管道的作用是把上一个进程的输出作为下一个进程的输入,利用管道可以把若干命令连接在一起。

(3)管道的实现机制基于内核中的文件系统pipefs,它会为每个管道文件分配一个环形缓冲区,以支持读/写操作。进程可以使用两种类型的管道进行通信:匿名管道和命名管道。
匿名管道是只支持在父子进程或兄弟进程之间通信的管道,一般使用方式为父进程调用pipe()创建匿名管道,子进程默认继承父进程打开的管道。匿名管道的特点是无需创建额外的文件,直接使用内存进行通信,因此速度快,但通信范围有限。
命名管道是支持任意进程间通过管道通信的管道,进程通信前需要先创建fifo类型的特殊文件,读写进程再分别打开该文件进行读写。命名管道的特点是需要创建额外的文件进行通信,速度相对较慢,但通信范围广泛。

 

 (4)在Linux系统中,使用管道进行进程间通信的过程通常包括以下几个步骤:

①创建管道:通过pipe(系统调用创建一个管道文件,返回两个文件描述符,一个用于写入数据,另一个用于读取数据。

②创建进程:通过fork()系统调用创建一个子进程, 子进程会继承父进程的文件描述符。

③写入数据:在父进程中,使用write()系统调用将数据写入管道的写入文件描述符。数据会进入环形缓冲区中。

④读取数据:在子进程中,使用read(系统调用从管道的读取文件描述符中读取数据。数据会从环形缓冲区中被读取出来。

⑤关闭文件描述符:在使用完管道后,需要关闭文件描述符以释放资源。使用close0系统调用关闭文件描述符。

(5)Linux的进程管道是一种高效、 简洁的进程间通信机制,适用于需要进行快速数据传输的场景。同时,由于管道是基于文件系统的机制,因此还具有较好的可靠性和扩展性。

(6)实例:将/etc/passwd中的用户按UID数值大小排序并显示前3行。

注意:“-t”指定字符分段符;

           “-k”指定字段;

           “-n”表示按数值大小排序

[root@localhost ~]# sort -t ":" -k3 -n /etc/passwd |head -3
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
示例

(7)实例:统计出最占CPU的5个进程。

[root@localhost ~]# ps aux --sort=-%cpu |head -6
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root       2198  0.2  4.9 3764648 197728 ?      Sl   19:33   0:34 /usr/bin/gnome-shell
root        829  0.1  0.1 295564  5308 ?        Ssl  19:32   0:16 /usr/bin/vmtoolsd
root       2461  0.1  0.6 608748 25616 ?        Sl   19:33   0:16 /usr/bin/vmtoolsd -n vmusr
root          1  0.0  0.1 193908  7052 ?        Ss   19:32   0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root          2  0.0  0.0      0     0 ?        S    19:32   0:00 [kthreadd]
示例