fork,execlp在Linux中

时间:2011-10-22 16:54:58

标签: c linux

#include <unistd.h>
#include <stdio.h>


int main(int argc, char* argv[])
{

  int f1[2], f2[2];
  char buff;

  if(pipe(f1) != -1);
   printf("Pipe1 allright! \n");

  if(pipe(f2) != -1);
   printf("Pipe2 allright \n");



  if(fork()==0)
  {
    close(1);
    dup(f1[1]);
    close(0);
    execlp("ls", "ls", "-l", NULL);  
  }
  else
  {
    if(fork()==0)
    {  
    close(0);
    dup(f1[0]);
    close(1);
    dup(f2[1]);
     execlp("grep", "grep", "^d", NULL); 
    }
    else 
    {
        if(fork()==0)
        {
            close(0);
            dup(f2[0]);
            execlp("wc", "wc", "-l", NULL); 
      } 
    }

  }

  return 0;

}

我正在尝试做ls -l | grep ^ d | wc -l in C.

我尝试过每一次......

有什么问题? :(

输出:Pipe1好吧!,Pipe2好吧!

聚苯乙烯。你的帖子没有太多的上下文来解释代码部分;请更清楚地解释一下你的情景。

2 个答案:

答案 0 :(得分:3)

您的代码存在一些问题:

if(pipe(f1) != -1);
  printf("Pipe1 allright! \n");

我认为这应该是真正的错误检查,因此请删除;行中的if

运行程序之后您会注意到,grepwc命令仍在那里,它们不会终止。使用ps(1)命令进行检查。 ls命令似乎已经终止。

我们假设,四个过程的pid是:

  • 9000(主要)
  • 9001(ls)
  • 9002(grep)
  • 9003(wc)

展望/proc/9002/fd您会看到,文件句柄0(stdin)仍然可供阅读:

> ll /proc/9002/fd/0
lr-x------ 1 as as 64 2011-10-22 20:10 0 -> pipe:[221916]

环顾四周,谁有这个句柄仍然打开

> ll /proc/*/fd/* 2>/dev/null | grep 221916

您会看到,此管道的许多句柄已打开:grepwc都打开了两个。其他管道手柄也是如此。

解决方案:

您必须在dup 严格后关闭管道手柄。看这里:

#include <unistd.h>
#include <stdio.h>


int main(int argc, char* argv[])
{
     int f1[2];
     char buff;

     if(pipe(f1) != -1)
          printf("Pipe1 allright! \n");

     int pid = fork();
     if(pid==0)
     {
          close(1);
          dup(f1[1]);

          close(f1[0]);
          close(f1[1]);

          close(0);
          execlp("ls", "ls", "-l", NULL);  
     }
     printf("ls-pid = %d\n", pid);

     int f2[2];
     if(pipe(f2) != -1)
          printf("Pipe2 allright \n");

     pid = fork();
     if(pid==0)
     {  
          close(0);
          dup(f1[0]);

          close(f1[0]);
          close(f1[1]);

          close(1);
          dup(f2[1]);

          close(f2[0]);
          close(f2[1]);

          execlp("grep", "grep", "^d", NULL);
          // system("strace grep '^d'"); exit(0);
     }
     printf("grep-pid = %d\n", pid);

     close(f1[0]);
     close(f1[1]);

     pid = fork();
     if(pid==0)
     {
          close(0);
          dup(f2[0]);
          close(f2[0]);
          close(f2[1]);

          execlp("wc", "wc", "-l", NULL); 
     }
     printf("wc-pid = %d\n", pid);

     close(f2[0]);
     close(f2[1]);
}

答案 1 :(得分:1)

您可能希望使用dup2而不是dup,即代替

close(1);
dup(f1[1]);

DO

dup2(f1[1], 1);
其他发生的

等等