重定向 dup2

int dup(int fd)

重定向文件描述符  int newFd = dup(STDOUT_FILENO)

newFd 指向 stdout

int dup2(int fd1, int fd2)

重定向文件描述符  dup2(newFd, STDOUT_FILENO)

stdout 指向 newFd

重定向输入输出到管道

例子1: 父进程标准输入后,有子进程进行标准输出

void testDup()

{

int fds[2];

pid_t pid;

char buf[128];

if(pipe(fds))

{

printf("file:%s,line:%d",__FILE__,__LINE__);

perror("fail pipe!");

return ;

}

pid=fork();

if(pid<0)

{

printf("file:%s,line:%d",__FILE__,__LINE__);

perror("fail fork!");

return ;

}

else if(pid==0)

{

close(fds[1]);

//直接输出

dup2(STDOUT_FILENO,fds[0]);

}

else

{

close(fds[0]);

dup2(STDIN_FILENO,fds[1]);

//父进程接受键盘输入

while(1)

{

fprintf(stderr,"parent send:");

memset(buf,0,sizeof(buf));

read(STDIN_FILENO,buf,sizeof(buf));

write(fds[1],buf,strlen(buf));

}

close(fds[1]);

}

return ;

}

例子2: ls | more 类似实现

思路:

1.ls 的输出,是输出到  STDOUT

2.more 的输入,是从 STDIN 接受

3.我们要实现 ls 的输出,作为 more 的输入

4.所以我们要创建管道,然后,把 STDOUT 和 STDIN 重定向到管道

5.这样 我们就实现了: 连接 ls 和 more

19重定向管道与popen模型-LMLPHP

void testDup2()

{

int fds[2];

pid_t pid;

if(pipe(fds))

{

printf("file:%s,line:%d",__FILE__,__LINE__);

perror("fail pipe!");

return ;

}

pid=fork();

if(pid<0)

{

printf("file:%s,line:%d",__FILE__,__LINE__);

perror("fail fork!");

return ;

}

else if(pid==0)

{

close(fds[1]);

dup2(fds[0],STDIN_FILENO);

printf("\n");

execlp("more","more","-d",NULL);

close(fds[0]);

}

else

{

close(fds[0]);

dup2(fds[1],STDOUT_FILENO);

execlp("ls","ls","-b",NULL);

close(fds[1]);

}

}

popen 模型

FILE *popen(const char *cmd, char *type)

解析:

创建子进程,并调用exec,指向cmd命令

同时建立管道,用于父子进程标准输入输出

type取值 “ r ” :       数据由子进程流到父进程

type取值 “ w ”:       数据由父进程流到子进程

int   pclose(FILE *stream)

popen第一参数与exec的区别:

popen第一参数包括了命令的名称,参数。如:popen(”ps -ef”,”r”)作为第一参数。

exec是路径、名称、参数分开多个部分作为exec的参数传入。如exec(“ps”,”ps”,”-ef”);

例子:排序

void testPopen()

{

int arr[]={2,4,5,77,11,22,633,21,4};

FILE *file=popen("sort -n","w");

if(!file)

{

printf("file:%s,line:%d",__FILE__,__LINE__);

perror("fail open file!");

return ;

}

int i=0;

for(;i<sizeof(arr)/sizeof(arr[0]);++i)

{

fprintf(file,"%d\n",arr[i]);

}

pclose(file);

}

例子2:通过 popen 实现  ps -ef | grep pts

思路:

1.使用popen模型分别调用ps –ef, grep pts:

pRead = popen("ps -ef", "r")

pWrite= popen("grep pts", "w")

2.此时pRead,pWrite就是两个文件指针,进行文件读写操作。

3. 从 pRead中读取数据,写入到 pWrite中。

void testPopen2()

{

FILE *pRead=popen("ps -ef","r");

FILE *pWrite=popen("grep pts","w");

if(!(pRead&&pWrite))

{

printf("file:%s,line:%d",__FILE__,__LINE__);

perror("fail open file!");

return ;

}

char buf[1024];

while(fgets(buf,sizeof(buf),pRead))

{

fputs(buf,pWrite);

}

pclose(pRead);

pclose(pWrite);

}

05-11 15:20