您的位置:首页 > 运维架构 > Linux

通过管道和重定向实现linux管道命令(二)

2017-04-10 10:28 405 查看
    在我的“通过管道和重定向实现linux管道命令”当中实现cat file | sort命令,没有使用标准I/O函数库中提供的popen()函数和pclose()函数,在本文中,我们一起探讨一下通过这两个标准的I/O函数来实现上述这个命令。    先看一下这两个函数的定义吧:
FILE * popen(const char *command, const char *type);
    popen()函数用来创建一个管道并启动另外一个进程,新启动的进程要么从该管道当中读出标准输入(输入重定向),要么向该管道写入标准输出(输出重定向)。    具体的第二个参数type表示I/O模式的类型。如果command命令的输出作为其他命令的输入(输出重定向),type为“r”权限;如果command命令的输入为其他命令的输出(输入重定向),type为“w”权限。int pclose(FILE *stream);
    这个函数用来关闭由popen()创建的标准I/O流,等待其中的命令终止,然后返回给shll的终止状态。    在我们对"cat file | sort"程序进行修改之前,先看一个简单的程序:#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#define MAXLINE 80

int main()

{

    FILE *fp;

    char buf[MAXLINE], command[MAXLINE];

    int n;

    

    n = fgets(buf, MAXLINE, stdin);

    n = strlen(buf);

    if(buf[n-1] == '\n') {

        n--;

    }
/*有关snprintf()函数的是有,具体可查阅printf()函数族的使用*/
    snprintf(command, sizeof(command), "head %s", buf);

    fp = popen(command, "r");

    while(fgets(buf, MAXLINE, fp) != NULL) {

        fputs(buf, stdout);

    }

    pclose(fp);

    return 0;

}执行结果如下:^_^[sunny@sunny-laptop ~/summer]47$ ./a.out

file            //file是我的输入,下面都是file文件当中的内容

dsf

abcde

92381

8232

sadf

872

1988

2000

1022

2012

^_^[sunny@sunny-laptop ~/summer]48$
    程序说明:在调用popen()函数,就是创建了一个新的进程,同时创建了一个管道,注意,type的类型为“r”说明这里是输出重定向,也就是将command的输出作为其他命令的输入,写到创建的管道当中,并不是将其执行的结果输出到标准输出上。下来的话,通过对fp流的读取操作,读取管道当中command的输出结果,为了查看结果是不是正确的,我们将其显示在了标准输出。    下面实现"cat file | sort"命令:#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#define MAXLEN 80

#define MAX 1024

int main()

{

    FILE *fpin, *fpout;

    char command1[MAXLEN]={0}, command2[MAXLEN]={0}, buff[MAX]={0};

    snprintf(command1, sizeof("cat file"), "cat file");

    snprintf(command2, sizeof("sort"), "sort");

    fpin = popen(command1, "r"); //输出重定向

    fpout = popen(command2, "w"); //输入重定向

    while(read(fileno(fpin), buff, MAX) != 0) {

        write(fileno(fpout), buff, MAX);

    }

/*

 *或者这个while循环可以用这个while循环来代替

 *

    while(fgets(buff, MAX, fpin) != NULL) {

        fputs(buff, fpout);

    }

*/

    pclose(fpin);

    pclose(fpout);

    return 0;

}    这个程序的执行结果是:^_^[sunny@sunny-laptop ~/summer]84$ ./a.out

1022

1988

2000

2012

8232

872

92381

abcde

dsf

fan

sadf

^_^[sunny@sunny-laptop ~/summer]85$    程序说明:首先使用snprintf()函数将两个通过管道要执行的命令分别存放在command1和command2当中,然后调用popen函数两次,第一个是所谓的输出重定向,将cat file的结果输入到popen()创建的管道当中,第二个是所谓的输入重定向,将管道当中的数据作为sort命令的输入。之后,通过一个while()循环,读取第一个管道当中的数据到buff变量当中,然后把buff变量当中的数据输入到第二个管道当中,作为sort命令的输入。    小结:在这次实现这个命令的时候,是创建了两个管道,之前的话,只有创建了一个管道就可以实现,但是如果要通过这两个标准的I/O函数来实现的话,我目前没有想到只创建一个管道就来实现的方法。


<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>

阅读(2929) | 评论(0) | 转发(0) |

0
上一篇:向IPC进发

下一篇:有名管道(FIFO)实现无亲缘关系的客户服务器

相关热门文章
test123

编写安全代码——小心有符号数...

彻底搞定C语言指针详解-完整版...

使用openssl api进行加密解密...

一段自己打印自己的c程序...

linux dhcp peizhi roc

关于Unix文件的软链接

求教这个命令什么意思,我是新...

sed -e "/grep/d" 是什么意思...

谁能够帮我解决LINUX 2.6 10...

给主人留下些什么吧!~~

评论热议
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: