进程间通信(三)——shell实现(dup2)

2023-11-04 03:58

本文主要是介绍进程间通信(三)——shell实现(dup2),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

无名管道(2):shell管道的实现

小技巧:统计一个文件下有多少行代码?

wc -l 文件名

  • 就能得到文件的行数

搭配使用

cat pipe.c | wc -l

小技巧:搜索文件里面的内容

grep "#include" 文件名

小技巧:查看命令在什么地方

whereis ls

Shell中的管道通信

管道的作用

  • Shell中具有亲缘关系的进程之间传递消息
  • 管道的本质是一个字节流

cat pipe.c | wc -l

将标准输出重定向到管道里面

 

在shell中运行命令

  • 基本流程和重定向功能
    •  封装成进程:fork/exec系统调用
    •  该进程默认打开的stdin、stdout、stderr连接在终端上
    •  运行的命令从键盘读取数据并且把输出和错误消息写到屏幕上
    •  通过重定向,可以从指定文件读取数据,或将数据输出到指定文件
    •  重定向I/O的功能是由shell本事实现的:标准流与文件的连接
    •  程序本身并不知道数据最后流向哪里:只是标准流打交道
    •  通过命令:cmd>file告诉shell将stdout定位到文件file,于是shell就将文件描述符与指定的文件连接起来,程序的输出到file,而不是默认的屏幕

输入输出重定向

使用ls > log 重定向,是怎么实现重定向的?

就是使用dup函数和dup2函数实现的

重定向一般操作stdin(0)、stdout(1)、stderr(2)这个东西

dup函数和dup2函数

  • 将管道和输入输出设备联系起来
  • 输入、输出重定向到某个设备、文件
  • int dup (int oldfd);
  • 打开一个已经存在的文件描述符,返回值为新的文件描述符
  • 可以利用这个返回的文件描述符,对这个文件描述符进行文件操作
  • #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <string.h>int main(void)
    {int new_fd;new_fd = dup(1);write(1, "hello", strlen("hello"));write(new_fd, "world\n", strlen("world\n"));close(new_fd);return 0;
    }

int dup2(int oldfd, int newfd);

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#define handle_error(s) \{perror(s);exit(-1);}
int main(int argc, char *argv[])
{int fd, new_fd;char *buf = "hello world\n";fd = open("data.log", O_RDWR|O_CREAT, 0664);if (fd == -1)handle_error("open");new_fd = dup2(fd, 1);   //把stdout重定向为和fd一模一样的句柄if (new_fd == -1)handle_error("dup2");printf("fd: %d\n new_fd:%d\n", fd, new_fd);write(1, buf, strlen(buf));close(fd);return 0;
}

实验结果:没有输出到屏幕上,重定向到了其他文件,这个用的应该最多

  1. 实现原理:
    • 复制文件描述符:dup2
    • 编程练习
    • 一个程序的标准输出定向到管道中
    • 而另一个程序的标准输入重定向到管道中读取
  2. 实现步骤
    1. 定义一个无名管道
    2. fork,使用两个进程对数据进行收发
    3. 子进程把标准输出重定向到写管道
    4. 父进程把标准输入重定向到读管道
    5. 其实管道的底层实现流程就像下面一样
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>#define handle_error(s) \{perror(s);exit(-1);}int main(int argc, char *argv[])
{int pipe_fd[2];if (pipe(pipe_fd) == -1){perror("pipe");exit(-1);}else{int ret_from_fork = fork();if (ret_from_fork == 0){dup2(pipe_fd[1], 1);execlp("cat", "cat", "dup.c", NULL);}else{dup2(pipe_fd[0], 0);close(pipe_fd[1]);execlp("grep", "grep", "include", NULL);}}return 0;
}

int dup3(int oldfd, int newfd, int flags);

这篇关于进程间通信(三)——shell实现(dup2)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/343062

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现

[Linux]:进程(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 进程终止 1.1 进程退出的场景 进程退出只有以下三种情况: 代码运行完毕,结果正确。代码运行完毕,结果不正确。代码异常终止(进程崩溃)。 1.2 进程退出码 在编程中,我们通常认为main函数是代码的入口,但实际上它只是用户级