通常将一个进程的输出通过管道连接到另一个进程的输入,linux下已经对shell命令里管道符号“|”太熟悉了,起到了命令连接的作用,比如命令
[lihui@localhost ~]# lspci | grep Network 0b:00.0 Ethernet controller: Intel Corporation 82599EB 10-Gigabit SFI/SFP+ Network Connection (rev 01) 0b:00.1 Ethernet controller: Intel Corporation 82599EB 10-Gigabit SFI/SFP+ Network Connection (rev 01) 12:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01) 12:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
用户键盘的输入lspci为标准输入,这条命令就能输出一些信息,这里是标准输出,会将这些标准输出传递给grep Network作为它的标准输入,shell实际上将标准输入和标准输出进行了重新连接,使得数据流从键盘输入通过两个命令最终输出到屏幕上
管道pipe由下面函数创建:
#include <unistd.h> int pipe(int filedes[2]);
参数是一个由两个整数类型的文件描述符组成的数组的指针,经过参数filedes返回两个文件描述符,filedes[0]以读打开,filedes[1]以写打开,而filedes[1]的输出就是filedes[0]的输入,也就是写到filedes[1]的所有数据都可以从filedes[0]里读回来,数据基于先进先出的原则处理,所以读的次序和写的次序是一致的;函数成功返回0,出错返回-1
创建一个简单的管道
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #define MAX_SIZE 20 int main(){ int data_len; int filedes[2]; char *str = "Hello world"; char buffer[MAX_SIZE]; memset(buffer, 0, sizeof(buffer)); if (!pipe(filedes)){ data_len = write(filedes[1], str, strlen(str)); printf("Have written %d bytes\n", data_len); data_len = read(filedes[0], buffer, MAX_SIZE); printf("Have read %d bytes: %s\n", data_len, buffer); exit(0); } return 0; }
运行结果:
[lihui@localhost ~]# ./a.out Have written 11 bytes Have read 11 bytes: Hello world
pipe创建管道之后,通过文件描述符filedes[1]写入数据,然后再从filedes[0]读出数据,假如这时刻手痒,想看看假如从filedes[0]写数据,然后从filedes[1]读出数据,会不会报错,那就将两个文件描述符进行更换:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #define MAX_SIZE 20 int main(){ int data_len; int filedes[2]; char *str = "Hello world"; char buffer[MAX_SIZE]; memset(buffer, 0, sizeof(buffer)); if (!pipe(filedes)){ data_len = write(filedes[0], str, strlen(str)); printf("Have written %d bytes\n", data_len); data_len = read(filedes[1], buffer, MAX_SIZE); printf("Have read %d bytes: %s\n", data_len, buffer); exit(0); } return 0; }
运行结果,果然报错了:
[lihui@localhost ~]# ./a.out Have written -1 bytes Have read -1 bytes:
可见怀疑也要找没有明文规定的东西来针对~!