进程间通信(三)——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);

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
『软件信息』 软件名称: diablo2oo2's Universal Patcher v2.18.3 汉化版 软件语言: 中文 软件类型: 补丁制作 授权方式: 免费软件 运行环境: Win2003, WinXP, Win2000, WinNT, WinME, Win9X 软件大小: 1.94 MB 开 发 商: http://diablo2oo2.cjb.net 软件汉化: tracky([email protected]) 『软件简介』 一款极佳的文件补丁工具,可以进行自由定制。 程序主要功能: 1.支持对多个文件应用补丁 2.支持创建偏移或搜索 & 替换补丁/Loader 3.支持对不同大小的文件进行比较 (实偏移与虚拟地址) 4.支持注册表补丁,同样支持 Loader 5.支持在补丁中附加文件 6.支持从注册表中获取文件路径 7.支持 CRC32 与文件大小校验 8.支持对已加壳的文件进行补丁 9.支持对生成的补丁加壳 10.支持工程 11.支持补丁使用自定义皮肤 12.支持在补丁中添加音乐(xm、mod、it、s3m、mtm、umx、v2m、ahx) 13.还有更多功能期待您的发现... 『更新内容』 1.为 Windows Vista 使用 ShellExecute 替换 WinExec API 2.修复在编辑“搜索与替换出现次数”对话框中的 Bug 3.加入对皮肤按钮 ID 的检查 4.增强用于调整窗口大小的引擎 5.加入了“从注册表值中提取路径”选项 6.Loader 支持保存目标文件路径到 INI 文件中 7.加入了用于播放 .sid 文件的 TitchySID 播放器 8.为“附加文件”加入了新的选项: 覆盖已存在的文件 9.加入了对禁用应用补丁按钮皮肤的支持 10.加入了多语言支持 11.修复悬停提示宽度的 Bug。现在较长的内容将会分多行显示。 12.使用新版本的 MASM v10 进行编译。 13.修复在执行附加文件时的 Bug。 14.修复资源(皮肤)更新模块的 Bug。 15.将补丁中使用的字符串加入到标准模板的标准资源中,方便修改。 『汉化说明』 1.汉化完全版,安装即可使用,无需原版。 2.如果遇到问题,请与我联系! 3.推荐喜欢自定义补丁颜色的朋友使用 cnhhkk 制作的 dUP2 的颜色辅助 设置工具 - dUP 2 Color Panel。 主页地址:http://cnhhkk.21windows.cn 镜像地址: http://vip.hanzify.org/tracky/dUP2ColorPanel.rar http://vip.hanzify.org/tracky/dUP2ColorPanel11.rar tracky 2008.11.23

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值