《精通Unix下C语言编程与项目实践》之七——标准I/O重定向

不拘一个遍程序系列程序不能一个脑袋钻到底,有时要学会变通,即所谓的曲线救国。
我的诗歌:都是我的打油诗,但是很值得一读。不要工作还衣食无忧之四难歌   香格里拉美人图
宝宝图片:超可爱的小宝宝 博客
考试培训:主要是关于考研、软考和等级的相关题解。2009考研试题分析   2008年12月程序员试题分析    2009年软考备考全攻略    2008年5月程序员试题解析
 
 
 
《精通Unix下C语言编程与项目实践》之七
标准I/O重定向 
作者:朱云翔,胡平

11.2.4 连接标准I/O的管道模型

管道在shell中最常见的应用是连接不同进程的输入输出,比如使A进程的输出变成B进程的输入等。考察shell命令“cat pipe3.c | more”,进程“more”使用了进程“cat pipe3.c”的输出。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

1. 分别重定向标准输入、标准输出、标准错误输出到文件描述符fd1fd2fd3中。

答:复制文件描述符fd1到文件描述符0中即可重定向标准输入,其它的类似,如以下语句所示:

dup2(fd1, 0);   /* 复制fd1到文件描述符0中,更改标准输入为fd1 */

dup2(fd2, 1);   /* 复制fd2到文件描述符1中,更改标准输出为fd2 */

dup2(fd3, 2);   /* 复制fd3到文件描述符2中,更改标准错误输出为fd3 */

当执行“dup2(fd1, 0)”后,文件描述符0就对应到了fd1所对应的文件中,而一些标准输出函数,如printfputs等仍然向描述符0中写入内容,从而达到了重定向的效果。

模型

使用管道将父进程标准输入连接到子进程标准输入的方法如下:

(1) 创建管道,返回无名管道的两个文件描述符fildes[0]fildes[1]

(2) 创建子进程,子进程中继承无名管道文件描述符。

(3) 父进程关闭管道的输出端,即关闭只读文件描述符fileds[0]

(4) 父进程将标准输出(stdout,文件描述符1)重定向为文件描述符fileds[1]

(5) 子进程关闭管道的输入端,即关闭只写文件描述符fileds[1]

(6) 子进程将标准输入(stdin,文件描述符0)重定向为文件描述符fileds[0]

最终创建的管道流如图11-7所示:

11-7 父子进程标准I/O管道(父进程流向子进程)

实例

本处设计一个将父进程标准输出流连接到子进程标准输入流的管道,父进程向stdout输出的“Hello!”直接转移到子进程的stdin,由子进程“gets(buf)”语句所获取。如代码11-6所示:

代码11-6 父进程的输出连接子进程的输入通信实例(节自/code/chapter11/pipe3.c

#include <unistd.h>

#include <stdio.h>

int main()

{

    int fildes[2];

    pid_t pid;

    int i, j;

    char buf[256];

    if (pipe(fildes) < 0 || (pid = fork()) < 0) /* 创建管道和子进程 */

    {

        fprintf(stderr, "error!\n");

        return 1;

    }

    if (pid == 0)

    {

    /* ―――――――――――――――――子进程―――――――――――――――――― */

        close(fildes[1]);                  

        dup2(fildes[0], 0);                 /* 重定向stdinfildes[0] */

        close(fildes[0]);

        gets(buf);                          /* 读入输入,其实是读取父进程输出 */

        fprintf(stderr, "child:[%s]\n", buf);

        return 2;

    }

    /* ―――――――――――――――――父进程―――――――――――――――――― */

    close(fildes[0]);

    dup2(fildes[1], 1);                     /* 重定向stdoutfildes[1] */

    close(fildes[1]);

    puts("Hello!");                         /* 输出,同时增加子进程的输入信息*/

    return 0;                          

}

编译与运行代码11-6

# make pipe3

        cc -O -o pipe3 pipe3.c

# ./pipe3

child:[Hello!]

上例中,父进程的标准输出已经重定向到管道中,故父进程puts未能将结果打印到屏幕上

 
相关文章:
封面          前言        目录         策划         作者
动态库        变长参数    文件锁       外设         僵死进程
定时器        I/O重定向
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值