1,引入
前面说到,用pipe函数就能创建管道,但是它比较原始。我们需要自己创建子进程、自己创建管道、创建完管道获得管道的文件描述符后需要自己关闭管道两端的某些接口,需要自己在子进程里exec执行命令。
其实这些完全可以先封装好,于是有了下面的函数:
#include<stdlib.h>
FILE* popen(const char* cmdstring, const char* type);
int pclose(FILE* fp);
这两个函数总是成对使用,popen用于创建管道;pclose用于关闭管道。
type的可选值为“w”或“r”,代表可读与可写。代表popen返回的文件的属性。
popen(cmdstring, "r")代表:
- 你在当前程序与cmdstring(可以是一个cmd命令或者可执行文件)之间创建了一个管道;
- popen自己会创建子进程,在子进程里执行cmdstring,cmdstring的标准输出被绑定到管道的写端;
- 所以cmdstring的执行结果写入了管道
- popen返回该管道,在父进程(当前进程)我们可以读取这个管道里的内容了
2,例子
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
//15.3 popen
FILE* fp = NULL;
char buf[100] = {0};
//通过管道获取test.txt文件里的内容
//cat test.txt 的结果写入文件,并返回文件描述符
if((fp = popen("cat test.txt", "r")) == NULL) {
printf("popen error !\n");
exit(1);
}
//通过返回的文件指针读取文件内容
while(fgets(buf, 100, fp) != NULL) {
//每次读取一行,并打印
printf("%s", buf);
}
//这里注意记得关闭
pclose(fp);
exit(0);
}
我们首先在当前目录下创建一个test.txt文件,向里面随便写入一两行内容。
我们的cmdstring是“cat test.txt”. 所以执行这个命令,读取文件里的内容。这个内容并不是直接输出到屏幕,而是被我们用管道绑定到一个文件指针。
后面我们再通过这个文件指针读取内容。
执行结果如下:
➜ code g++ -g -W -o study_Linux study_Linux.c
➜ code ./study_Linux
i am your father!
thanks for all the fish!