【问题标题】:Using pipe in linux using parent and child process在linux中使用管道使用父子进程
【发布时间】:2013-05-06 20:30:48
【问题描述】:

我正在尝试使用 C 来实现这个 linux 命令。 ls -l |剪切 -b 1

我正在尝试这样做的方式是

在父进程中调用 ls -l 将 ls -l 的输出放入文件中(写入文件)

在子进程中调用 cut 读取文件(写在父进程中的那个) 对文件应用剪切 打印输出

这就是我目前所做的

/* pipe.c */
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

void main()
{
   int filedes[2];
   int p;
   pid_t pid, pid1;
   p=pipe(filedes);
   FILE *stream;
   char buff[20];
   
   printf("pipe command returns %d, %d ,%d\n",p, filedes[0],filedes[1]);
   
   if(pipe(filedes) == -1) /* Create the pipe */
      printf("error pipe");
      pid1=fork();
      pid=getpid();
      switch (pid1) { /* Create a child process */
      case -1:
         printf("error fork");
      case 0: /* Child */
      /* Close unused write end */
      /* Child can now read from pipe */
         if (close(filedes[1]) == -1)
            printf("error close");
         printf("I am a child process pid %d, and will read from pipe\n",pid);
         
         while (read(filedes[0], &buff, 1) > 0)
            write(STDOUT_FILENO, &buff, 1);

         write(STDOUT_FILENO, "\n", 1);
         close(filedes[0]);
         _exit(EXIT_SUCCESS);

         break;
         
         default: /* Parent */
         /* Close unused read end */
         /* Parent can now write to pipe */
         if (close(filedes[0]) == -1)
            printf("error close");
         printf("I am the parent process pid %d, and will write to pipe\n", pid );
         stream = fdopen(filedes[1], "w");
         strcpy(buff, "This is a test\n");
         write(filedes[1], buff, strlen(buff));

         char *args[80];
         args[0] = "ls";
         args[1] = "-l";
         args[2] = NULL;
         execvp(args[0],args);
  
         int bak, new;
         bak = dup(1);
         new = open("/home/urwa/abc.txt", O_WRONLY);
         dup2(new, 1);
         close(new);

           

         close(filedes[1]);          /* Reader will see EOF */
         wait(NULL);                /* Wait for child */
         exit(EXIT_SUCCESS);

         break;
   }
}

这段代码运行良好。并在支架输出处打印测试语句。以及 ls -l 输出。但文件是空的。我究竟做错了什么。 我也尝试了如下的 freopen .. 仍然是空文件。 :/

 FILE *fp;
 fp = freopen ("/temp/abc.txt", "a+", stdout);

【问题讨论】:

    标签: linux pipe parent-child


    【解决方案1】:

    你没有在孩子中调用cut,而且文件描述符在这里搞砸了。

    为了执行任务,您必须关闭父级的标准输出,并使父级的写入结束标准输出在执行vp之前。在孩子中,您必须关闭孩子的标准输入,并在 execvp 之前将读取结束为您孩子的标准输入。以这种方式your parent's stdout is stdin of your child(创建管道 b/w 两个)。

    int main()
    {
       int filedes[2];
       int p;
       pid_t pid = 0, pid1 = 0;
       p=pipe(filedes);
       FILE *stream;
       char buff[20];
       char *args[80];
    
       printf("pipe command returns %d, %d ,%d\n",p, filedes[0],filedes[1]);
    
       if(pipe(filedes) == -1) /* Create the pipe */
          printf("error pipe");
          pid1=fork();
          pid=getpid();
          switch (pid1) { /* Create a child process */
          case -1:
             printf("error fork"); break;
          case 0: /* Child */
          /* Close unused write end */
          /* Child can now read from pipe */
             if (close(filedes[1]) == -1)
                printf("error close");
             printf("I am a child process pid %d, and will read from pipe\n",pid);
    
             close(0); //close stdin of child
             dup(filedes[0]); //make pipes read end stdin of child
    
             args[0] = "cut";
             args[1] = "-b";
             args[2] = "1";
             args[3] = NULL;
             execvp(args[0],args);
             break;
    
             default: /* Parent */
             /* Close unused read end */
             /* Parent can now write to pipe */
             if (close(filedes[0]) == -1)
                printf("error close");
             printf("I am the parent process pid %d, and will write to pipe\n", pid );
    
             close(1); //close stdout
             dup(filedes[1]); //make write end of pipe stdout of parent
             args[0] = "ls";
             args[1] = "-l";
             args[2] = NULL;
             execvp(args[0],args);
             break;
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-03-07
      • 2020-12-07
      • 2019-02-27
      • 2012-03-04
      • 2017-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多