每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。
在 Linux 中,管道(Pipe) 是一种强大的进程间通信(IPC)机制,它允许将一个命令的输出作为另一个命令的输入,使多个命令组合使用,提高工作效率。
- 管道是一种最基本的进程间通信机制。 把一个进程连接到另一个进程的一个数据流称为一个“管道”,通常是用作把一个进程的输出通过管道连接到另一个进程的输入。
- 管道本质上是内核的一块缓存,内核维护了一块缓冲区与管道文件相关联,对管道文件的操作,被内核转换成对这块缓冲区内存的操作。
举例:
在shell中执行命令,经常会将上一个命令的输出作为下一个命令的输入,由多个命令配合完成一件事情。而这就是通过管道来实现的。|这个竖线就是管道符号
ls -l | grep string //grep是抓取指令
- ls命令(其实也是一个进程)会把当前目录中的文件都列出来
- 但它不会直接输出,而是把要输出到屏幕上的数据通过管道输出到grep这个进程中,作为grep这个进程的输入;
- 然后这个进程对输入的信息进行筛选(grep的作用),把存在string的信息的字符串(以行为单位)打印在屏幕上。
- 无名管道(Anonymous Pipe):使用
|
符号连接多个命令,数据在进程间传输,但不会存储在文件中。 - 有名管道(Named Pipe, FIFO):使用
mkfifo
命令创建一个持久化的管道文件,可供多个进程访问。
一) 无名管道(Anonymous Pipe)
无名管道是最常见的管道形式,使用 |
符号连接多个命令。
1.1 语法
command1 | command2 | command3
command1
的输出传递给 command2
作为输入,command2
的输出再传递给 command3
,以此类推。
1.2 示例
(1) 统计当前目录下的文件数量
ls -l | wc -l
ls -l
列出当前目录内容wc -l
统计行数,即文件数量
ps aux | grep bash
(3) 查找日志中包含 “error” 的行
cat /var/log/syslog | grep "error"
cat /var/log/syslog
显示日志内容grep "error"
过滤包含 “error” 的行
二) 有名管道(Named Pipe, FIFO)
有名管道(FIFO,全称 First In First Out)与无名管道类似,但它的数据存储在一个特殊的文件中,允许多个进程通过文件路径进行通信。
2.1 创建有名管道
使用 mkfifo
命令创建管道:
mkfifo mypipe
这将在当前目录下创建一个名为 mypipe
的管道文件。
2.2 进程间通信示例
(1) 终端 A:向管道写入数据
echo "Hello from process 1" > mypipe
(2) 终端 B:从管道读取数据
cat < mypipe
- 另一终端使用
cat
读取mypipe
里的数据。
如果 cat
先运行,会一直等待数据输入,直到 echo
命令写入数据。
三) 组合命令示例
(1) 按 CPU 使用率排序进程
ps aux | sort -nrk 3 | head -10
(2) 找出最常访问的 IP
cat access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -10
cat access.log
读取日志awk '{print $1}'
取出日志第一列(IP 地址)sort
排序uniq -c
统计每个 IP 出现的次数sort -nr
按次数倒序排列head -10
取前 10 个最常访问的 IP
4. 管道 vs. 重定向
操作 | 说明 | 示例 |
---|---|---|
**管道 (` | `)** | 连接多个命令 |
标准输入 (< ) |
从文件读取数据 | sort < file.txt |
标准输出 (> ) |
将输出写入文件(覆盖) | ls > output.txt |
追加输出 (>> ) |
将输出追加到文件 | echo "hello" >> file.txt |
- 管道
|
:用于将一个命令的输出作为另一个命令的输入,适用于短暂的进程间通信。 - 有名管道(FIFO):用于进程间数据传输,适用于需要持久化管道的场景。
- 结合
grep
、awk
、sort
等命令,可高效处理文本数据。
Entires个相关
除教程外,本网站大部分文章来自互联网,如果有内容冒犯到你,请联系我们删除!