Menu Close

管道

每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程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 统计行数,即文件数量

(2) 显示正在运行的进程中包含 “bash” 的进程

ps aux | grep bash
  • ps aux 列出所有进程
  • grep bash 筛选包含 “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
  • ps aux 显示所有进程
  • sort -nrk 3CPU 使用率排序(第 3 列)
  • head -10 取前 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):用于进程间数据传输,适用于需要持久化管道的场景。
  • 结合 grepawksort 等命令,可高效处理文本数据。

 

Entires个相关

除教程外,本网站大部分文章来自互联网,如果有内容冒犯到你,请联系我们删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Leave the field below empty!