Linux 中的管道是什么?管道重定向是如何工作的?

494d21145b5053a43a944f4e8522ff45.gif

作者 | 刘光录

来源 | TIAP

我们在命令行中经常会用到类似 cmd0 | cmd1 | cmd2 的写法。其实,这是管道重定向(pipe redirection),用于将一个命令的输出作为输入重定向到下一个命令。

那么,你知道它具体是怎么工作的吗?今天我们来详细了解一下。

注:本文中会有多个地方使用 Unix 这个术语(而不是Linux),因为管道的概念起源于 Unix。

Linux 中的管道:总体思路

以下是关于“什么是 Unix 管道?”的内容:

Unix 管道是一种 IPC(Inter Process Communication,进程间通信)机制,它将一个程序的输出转发到另一程序的输入。

现在,我们换一种更加专业且易懂的语言重新解释一下:

Unix 管道是一种 IPC(Inter Process Communication,进程间通信)机制,它接收程序的标准输出(stdout),并通过缓冲区将其转发给另一个程序的标准输入(stdin)。

这样的描述,大家应该能理解了。参考下图可以了解管道的工作原理:

1415685ede40f1bf68540a03d8c6097a.jpeg

管道命令的最简单示例之一是将一些命令输出传递给 grep 命令以搜索特定字符串。

比如,我们可以搜索名称包含txt的文件,如下所示:

1651f536a0cc292b692764a1f4d2ea19.png

管道将标准输出重定向到标准输入,但不是作为命令参数

有个非常重要的一点需要注意,管道命令将标准输出(stdout)传递到另一个命令的标准输入(stdin),但不是作为参数。下面我们举个例子来说明这一点。

如果我们不带任何参数使用 cat 命令,它默认会从 stdin 读取内容。看下面的例子:

$ cat
Hello, my friend.
^D
Hello, my friend.

在上面的例子中,没有带任何参数使用了 cat,因此它默认会读取 stdin。接下来,我写了一行文字,然后按键 Ctrl+d 告诉它我写完了(Ctrl+d 表示 EOF 或文件结束)。随后,cat 命令读取 stdin,然后把之前我写的那行文字输出到了终端中。

现在,看如下命令:

echo hey | cat

管道右边的命令并不等于 cat hey。这里,标准输出(stdout)"hey" 被放在了缓冲区(buffer),并被传输到了 cat 命令的标准输入(stdin)。由于没有命令行参数,所以 cat 默认读取 stdin,而 stdin 中恰好有了内容(即“hey”),因此 cat 读取了这个内容,并将其打印到 stdout。

为了演示这个区别,我们可以创建一个名为 hey 的文件,并在其中添加一些文本。参见下图:

85e58eebd7aea35132be827f50824977.png

Linux 中的管道类型

Linux 中有两种类型的管道:

1)匿名管道,也就是未命名管道;

2)命名管道。

匿名管道

顾名思义,匿名管道就是没有名称。当你使用 | 符号时,它们就会由 Unix shell 动态创建了。

我们通常所说的管道,就是指的匿名管道。它用起来很方便,作为最终用户,我们不需要跟踪它的运行,shell 自动会处理这一切。

命名管道

这个稍有不同,命名管道在文件系统中确实存在。它们像普通文件一样存在,可以使用下面的命令创建命名管道:

mkfifo pipe

这将创建一个名为 pipe 的文件,执行以下命令:

$ ls -l pipe
prw-r--r--. 1 gliu gliu 0 Aug 4 17:23 pipe

请注意开头的“p”,这意味着该文件是一个管道。现在我们来使用这个管道。

如前所述,管道将命令的输出转发给另一个命令的输入。这就像快递服务,你把包裹从一个地址送到另一个地址。因此,第一步是提供包裹。

echo hey > pipe

我们会看到 echo 信息没有打印出来,看起来像是被挂起了。新打开一个终端,尝试读取该文件:

cat pipe

我们看下两个终端的输出结果,如下图所示:

74e4bc1d1734fb9cb58c62935e65b495.jpeg

惊讶吗?这两个命令同时完成了执行。

这是普通文件和命名管道之间的基本区别之一。在其他进程读取管道之前,不会将任何内容写入管道。

那么,为什么要使用命名管道呢?我们来看一下。

命名管道不会占用磁盘上的任何内存。

如果我们执行命令 du -s pipe,就会发现它不会占用任何空间。这是因为命名管道就像从内存缓冲区读写的端点。写入命名管道的任何内容实际上都存储在临时内存缓冲区中,当从另一个进程执行读取操作时,该缓冲区将被刷新。

节省 IO

因为写入命名管道意味着将数据存储到内存中的缓冲区中,因此如果涉及大文件的操作的话,就会大幅减少磁盘 I/O。

两个不同进程之间的通信

通过使用命名管道,可以高效地从另一个进程实时获取事件的输出。因为读和写同时发生,所以没有等待时间。

较低层次的管道理解(针对高级用户和开发人员)

接下来我们更深入的讨论一下管道,以及具体的实现。这些需要对以下内容有基本的了解:

  • C 程序工作原理;

  • 什么是系统调用;

  • 什么是进程;

  • 什么是文件描述符。

我们不会很详细的介绍这些概念,只讨论与管道相关的内容。对于大多数Linux用户来说,下面的内容可以选择性的阅读。

为了进行编译,在文章最后提供了一个示例 makefile。当然,这只是用来说明的伪代码。

看以下程序:

// pipe.c
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <errno.h>extern int errno;int main(){
signed int fd[2];
pid_t pid;
static char input[50];
static char buf[50];pipe(fd);if((pid=fork())==-1){
int err=errno;perror("fork failed");
exit(err);}if(pid){close(fd[1]);read(fd[0], buf, 50);
printf("The message read from child: %s\n", buf);} else {close(fd[0]);
printf("Enter a message from parent: ");
for(int i=0; (input[i]=getchar())!=EOF && input[i]!='\n' && i<49; i++);write(fd[1], input, 50);
exit(0);}
return 0;
}

在第16行,我使用 pipe() 函数创建了一个匿名管道,传递了一个长度为 2 的带符号整数数组。

这是因为管道只是一个包含两个无符号整数的数组,代表两个文件描述符。一个用于写,一个用于读。它们都指向内存上的缓冲区位置,通常为1mb。

这里我将变量命名为fd。fd[0] 是输入文件描述符,fd[1] 是输出文件描述符。在该程序中,一个进程将字符串写入 fd[1] 文件描述符,另一个进程从 fd[0] 文件描述符读取。

命名管道也一样,使用命名管道(而不是两个文件描述符),你可以从任何一个进程中打开一个文件,并像其他文件一样对其进行操作。同时应记住管道的特性。

下面是一个示例程序,它执行与前一个程序相同的操作,但它创建的不是匿名管道,而是命名管道:

// fifo.c
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>extern int errno;#define fifo "npipe"int main(void){
pid_t pid;
static char input[50];
static char buf[50];
signed int fd;mknod(fifo, S_IFIFO|0700, 0);if((pid=fork())<0){
int err=errno;perror("Fork failed");
exit(err);}if(pid){fd=open(fifo, O_RDONLY);read(fd, buf, 50);close(fd);
printf("The output is : %s", buf);remove(fifo);
exit(0);} else {fd=open(fifo, O_WRONLY);
for(int i=0; (input[i]=getchar())!=EOF && input[i]!='\n' && i<49; i++);write(fd, input, strlen(input));close(fd);
exit(0);}
return 0;
}

在这里,我使用 mknod 系统调用来创建命名管道。如你所见,虽然在完成时删除了管道,但你可以不使用它,只需要打开并写入本例中的 npipe 文件,就可以轻松的实现在不同进程之间的通信。

其实现实中,我们也不必创建两个管道来实现双向通信,匿名管道就是这样的。

以下是一个简单的 Makefile 的源代码示例(只是示例),将其与前面的程序放在同一个目录中(分别为 pipe.c 和 fifo.c)。

CFLAGS?=-Wall -g -O2 -Werror
CC?=clangbuild:
$(CC) $(CFLAGS) -o pipe pipe.c
$(CC) $(CFLAGS) -o fifo fifo.cclean:
rm -rf pipe fifo

以上就是本次分享的关于 Unix 管道的全部内容,欢迎讨论。

538b4dc4bc6a3cdf8e65331ef30a6439.gif

往期推荐

一篇文章了解 Docker 的安装、启动以及工作原理!

剖析 kubernetes 集群内部 DNS 解析原理

Docker 镜像和容器的导入导出及常用命令

如何从 Docker 镜像里提取 dockerfile!

223a0fbf76271733b3fd83ca91574ebc.gif

点分享

2cc4b698e2cbfb8ba78747de7fe9f7b3.gif

点收藏

7b9d5ef666607cfd3a8e3a0e4c48e82d.gif

点点赞

8ccc5cda518a52cc4942338c65a91e1f.gif

点在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/511211.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AliRTC 开启视频互动 “零计算” 时代

简介&#xff1a;在 2021 云栖大会《产业视频化创新与最佳实践》视频云主题论坛中&#xff0c;阿里云智能高级技术专家在《AliRTC 开启视频互动 "零处理" 时代》的主题演讲中&#xff0c;发布了阿里云视频云下一代实时交互解决方案 —RTC “零处理”&#xff0c;同时…

网易数帆Curve加入PolarDB开源数据库社区

简介&#xff1a;Curve社区签署阿里巴巴开源CLA(Contribution License Agreement, 贡献许可协议), 正式与阿里云PolarDB 开源数据库社区牵手。 Curve社区签署阿里巴巴开源CLA(Contribution License Agreement, 贡献许可协议), 正式与阿里云PolarDB 开源数据库社区牵手。 Polar…

新起之秀 DPU,正在掀起数据中心变革!

在全产业数字化转型趋势之下&#xff0c;网络数据呈海量增长态势&#xff0c;传统 CPU 解决方案已无法负载现有的业务量——数据处理的效能受到限制&#xff1b;上层的应用计算能力受到限制。此时&#xff0c;DPU 逢时而生&#xff0c;DPU能够通过对网络、储存、算力等资源的有…

阿里云数据库开源发布:PolarDB三节点高可用的功能特性和关键技术

简介&#xff1a;在3月2日的阿里云开源 PolarDB 企业级架构发布会上&#xff0c;阿里云数据库技术专家孟勃荣 带来了主题为《PolarDB 三节点高可用》的精彩演讲。三节点高可用功能主要为 PolarDB 提供金融级强一致性、高可靠性的跨机房复制能力&#xff0c;基于分布式共识算法同…

全员学习低代码,一汽大众领跑数智化转型背后的秘密

简介&#xff1a;500位低代码开发者&#xff0c;90%来自一线&#xff0c;低代码开发在一汽-大众百花齐放。 一汽-大众有500位低代码开发者&#xff0c;90%是来自一线的业务人员&#xff0c;他们如何用低代码解决身边的数字化需求&#xff1f;钉钉宜搭《102个开发者故事》走进一…

智领云CEO彭锋:DataOps,大数据的新战线

作者 | 彭锋 供稿 | 智领云 2008年我在我的第一份工作&#xff08;Ask.com&#xff09;中开始使用Hadoop。当时是因为昂贵的Oracle集群无法处理不断增加的分析工作量&#xff0c;公司不得不切换到Hadoop。随后在Twitter担任数据工程师的第二份工作中&#xff0c;我在第一线参…

宜搭小技巧|维护Excel太麻烦?Excel一键转应用,为你的工作减负

简介&#xff1a;只需6步&#xff0c;轻松学会「Excel一键创建应用」&#xff01; 在钉钉的聊天窗口中&#xff0c;每天都会流转数量巨大的Excel表格&#xff0c;用于信息收集和数据统计&#xff0c;但有时这些表格并不能很好地帮助到我们的工作&#xff0c;相反还会带来许多不…

阿里云发布第四代神龙架构,提供业界首个大规模弹性RDMA加速能力

简介&#xff1a;10月20日&#xff0c;2021年杭州云栖大会上&#xff0c;阿里云发布第四代神龙架构&#xff0c;升级至全新的eRMDA网络架构&#xff0c;是业界首个大规模弹性RDMA加速能力。 10月20日&#xff0c;2021年杭州云栖大会上&#xff0c;阿里云发布第四代神龙架构。相…

性能提升40%,阿里云神龙大数据加速引擎获TPCx-BB世界排名第一

简介&#xff1a;神龙大数据加速引擎&#xff0c;针对大数据常用组件&#xff0c;如Spark、Hadoop、Alluxio等,结合阿里云神龙架构的特性&#xff0c;进行软硬一体化优化&#xff0c;形成独一无二的性能优势&#xff0c;最终&#xff0c;使复杂SQL查询场景性能相比社区版spark提…

构造函数的原型和原型链

转载 https://blog.csdn.net/weixin_44976833/article/details/101322081 构造函数和原型和原型链 1.静态成员和实例成员 1.1静态成员 静态成员在构造函数本身上添加的成员,静态成员只能通过构造函数来访问 function Person(name,age){this.name name;this.age age; } /…

redis + lua实现分布式接口限流实现方案

作者 | 步尔斯特来源 | 步尔斯特前言redis lua脚本已然成为了单体项目主流的限流方案。redis凭借其特性成为了中间件的佼佼者&#xff0c;最新官方测试数据&#xff1a;读的速度是110000次/s写的速度是81000次/s。lua&#xff1a;减少网络开销&#xff1a;使用Lua脚本&#xf…

微服务用户为什么要用云原生网关

简介&#xff1a;下文将为你解说云原生网关如何助你解决一系列痛点&#xff0c;优雅玩转云上微服务架构升级。 作者&#xff1a;百丈 随着云原生技术的发展&#xff0c;微服务的架构选型也是日新月异。在 Kubernetes 重塑运维体系的云时代&#xff0c;我们在安全、降本提效、…

15 分钟实现企业级应用无损上下线

简介&#xff1a;很多用户量大并发度高的应用系统为了避免发布过程中的流量有损&#xff0c;一般选择在流量较小的半夜发布&#xff0c;虽然这样做有效果&#xff0c;但不可控导致背后的研发运维成本对企业来说是一笔不小的负担。基于此&#xff0c;阿里云微服务引擎 MSE 在应用…

基于 Observable 构建前端防腐策略

简介&#xff1a;To B 业务的生命周期与迭代通常会持续多年&#xff0c;随着产品的迭代与演进&#xff0c;以接口调用为核心的前后端关系会变得非常复杂。在多年迭代后&#xff0c;接口的任何一处修改都可能给产品带来难以预计的问题。在这种情况下&#xff0c;构建更稳健的前端…

动态卡片:富媒体内容井喷式增长下,新一代移动端动态研发的模式

简介&#xff1a;「蚂蚁动态卡片」新品发布会全程回顾 在 iOS 和 Android 系统近期推送的更迭版本中&#xff0c;系统环境已经逐渐发展出了将部分内容和服务前置化展示的趋势。 同时&#xff0c;伴随着富媒体内容井喷式增长以及内容的多样化、年轻化&#xff0c;一款移动应用…

Windows 上创建的文件,上传到 Linux 服务器,文件名乱码?

作者 | 刘光录来源 | TIAP先来说一下问题&#xff0c;在 Windows 下创建的一系列文件&#xff0c;上传到 Linux 服务器后&#xff0c;出现文件名乱码&#xff0c;导致文件无法读取的情况。事情的起因是这样的...最近有这样一个需求&#xff1a;在Java Web工程中读取本地某一个文…

阿里云成为首个通过“虚拟化云平台性能测试(大规模)”的云厂商

简介&#xff1a;2021年7月27日&#xff0c;在可信云大会上&#xff0c;中国信息通信研究院发布了《虚拟化云平台性能评估方法》&#xff0c;同时&#xff0c;宣布了阿里云成为首个通过“虚拟化云平台性能测试&#xff08;大规模&#xff09;”的云厂商&#xff0c;并获得“202…

阿里云神龙团队拿下TPCx-BB排名第一的背后技术

简介&#xff1a;阿里云自主研发的神龙大数据加速引擎获得了TPCx-BB SF3000世界排名第一的成绩。 一 背景介绍 近日&#xff0c;TPC Benchmark Express-BigBench(简称TPCx-BB)公布了最新的世界排名&#xff0c;阿里云自主研发的神龙大数据加速引擎获得了TPCx-BB SF3000排名第…

从中国移动财报透视:什么在支撑移动云发展韧性?

8 月 11 日&#xff0c;中国移动公布 2022 年中期业绩报告。报告显示&#xff0c;上半年中国移动营运收入达人民币 4969 亿元&#xff0c;同比增长 12.0%。净利润 703 亿元&#xff0c;同比增长 18.9%&#xff0c;盈利能力全球领先。其中&#xff0c;移动云收入达人民币 234 亿…

vue 前期准备,项目结构

环境 1、node -v 检测 没有就下载node&#xff0c;装到C盘 http://nodejs.cn/download/ 2、vue -v 检测 没有就 npm install -g vue/cli 或者 yarn global add vue/cli 安装脚手架 网址 https://cli.vuejs.org/zh/ 也可以从网址里找到…