| system() 函数与fork() 和 exec() 一起启动了一个程序。管道也有一对类似的函数: popen() 和  pclose() 
 popen() 和 pclose() 的原型是:
 
 #include <stdio.h>
 FILE *popen (const char *command, const char *mode)
 
 int pclose (FILE *stream)
popen() 函数在调用进程和 command 指定的程序之间创建一个管道。实际上是当前进程先 fork 出一个子进程,然后该子进程再调用 exec  函数族中的函数去执行 command ,同时还使用 pipe() 建立了一个连通进程和 command 的一个管道。调用进程既可以从管道读取也可以写入管道,这由 mode 参数决定。当 mode 为 'r' 时为进程读 command 的输出结果;如果 mode 为 'w' 时,表示进程给 command 输送些参数。在 glibc2.9 后增加了一个 'e' 选项,该选项相当于设置了 FD_CLOEXEC  选项,也就是说,command 不会用到进程里的文件描述符。
 
 
 函数返回的是普通的标准 I/O 流指针,通过它可以将需要处理的内容输送到 shell 命令进行处理。如果函数执行失败(可能是内部调用 fork() 或 pipe() 失败,抑或无法分配相应内存空间),则返回 NULL 。
 
 最后,需要调用 pclose() 函数以等待相应进程结束及 command 的的退出状态码。
 
 测试代码:
 
 [C++] 纯文本查看 复制代码 #include <stdio.h>
#include <stdlib.h>
#define MAXSTR 5
int main(void)
{
        int i;
        FILE *pipe_fp;
        char *strings[MAXSTR] = {"hello", "www", "groad", "net", "good"};
        if ((pipe_fp = popen("sort", "w")) == NULL) {
                perror("popen");
                exit(EXIT_FAILURE);
        }
        for (i = 0; i < MAXSTR; i++) {
                fputs(strings[i], pipe_fp);
                fputc('\n', pipe_fp);
        }
        pclose(pipe_fp);
        return (0);
}运行输出:
 上面程序,我们将要排序的字符串通过通用 popen() 返回的 I/O 流指针输送往 command 一侧,然后用 sort 命令进行排序。需要注意的是,popen() 绑定的是一个 shell,因此可以在执行的命令中使用各种扩展匹配符号及重定向符号,如我们将上面的 popen() 改成:popen("sort > /tmp/popen.txt", "w") ,那么在执行程序后,可以看到结果保存在 /tmp/popen.txt 中。beyes@beyes  :~/c/popen> ./popen good
 groad
 hello
 net
 www
 下面这个例子,创建了两个两个管道,一个用以读,一个用以写,模拟了一种全双工的工作情形:
 
 [C++] 纯文本查看 复制代码 
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
        FILE *pipe_in, *pipe_out;
        char readbuf[128];
        if ((pipe_in = popen("ls", "r")) == NULL) {
                perror("popen");
                exit(EXIT_FAILURE);
        }
        if ((pipe_out = popen("sort", "w")) == NULL) {
                perror("popen");
                exit(EXIT_FAILURE);
        }
        if (( pipe_out = popen("sort", "w")) == NULL) {
                perror("popen");
                exit(EXIT_FAILURE);
        }
        while (fgets(readbuf, 128, pipe_in))
                fputs(readbuf, pipe_out);
        pclose(pipe_in);
        pclose(pipe_out);
        return (0);
}
运行输出:
 beyes@beyes  :~/c/popen> ./popen2 popen
 popen2
 popen2.c
 popen.c
 |