简体   繁体   English

管道将一个程序的stdout重定向到另一个程序的stdin

[英]Piping to redirect stdout of one program to stdin of another

We have to write a C program that will essentially redirect stdin of one command/program to another command/program stdout, using pipes. 我们必须编写一个C程序,它将使用管道将一个命令/程序的stdin重定向到另一个命令/程序stdout。 If the program on the command line was passed ./a.out ls -l \\; more 如果命令行上的程序已通过./a.out ls -l \\; more ./a.out ls -l \\; more , it should redirect the stdout of ls -l to more , with the \\; ./a.out ls -l \\; more ,它应该将ls -l的stdout重定向到more ,用\\; being the delimiter. 作为分界线。 This program should work for any command/program that is in our path so: ./a.out cat filename.c \\; more 这个程序应该适用于我们路径中的任何命令/程序: ./a.out cat filename.c \\; more ./a.out cat filename.c \\; more , should be the same as typing: cat filename.c | more ./a.out cat filename.c \\; more ,应该与输入相同: cat filename.c | more cat filename.c | more . cat filename.c | more

My problem is that my program can't seem to exec properly or that the pipes are not working as expected. 我的问题是我的程序似乎无法正常执行或管道没有按预期工作。 Basically I'm just getting no output aside from the print statement debugging I have placed. 基本上我只是在我放置的print语句调试之外没有输出。 To be specific, the program prints: Exec... and then ERROR, which is all in the parent code. 具体来说,程序打印:Exec ...然后是ERROR,它们都在父代码中。

  #include <fcntl.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <unistd.h>
  #include <sys/types.h>
  #include <sys/wait.h>
  void pipeit(char * pro1, char * pro2, char * p1args[], char * p2args[])
  {
     pid_t pid;
     int fd[2];
     int st;
     pipe(fd);
     pid = fork();

     if(pid < 0)
     {
        printf("Error Forking...\n");
        exit(-1);
     }
     else if(pid == 0)
     {
        dup2(fd[1],1);
        close(fd[0]);
        close(1);
        printf("Exec 1...\n");
        execv(pro1, p1args);
        printf("ERROR\n");
     }
     else
     {
        waitpid(pid,&st,0);
        if(st<0)
        {
           printf("Child Error\n");   
        }
        dup2(fd[0],0);
        close(fd[1]);
        close(0);
        printf("Exec...\n");
        execv(pro2,p2args);
        printf("ERROR\n");
     }
     return;
  }
  /* THIS IS JUST COMMAND LINE PARSING */
  int main(int argc, char * argv[])
  {
     int i = 1;
     char * pro1;
     char * pro2;
     char * first[argc+1];
     char * second[argc+1];
     while(i<argc && argv[i][0] != ';')
     {
        if(i == 1)
        {
           pro1 = argv[i];
        }
        else
        {
           first[i] = argv[i];
        }
        i++; 
     }
     first[i] = NULL;
     while(i<argc)
     {
        if(argv[i][0] == ';')
        {
           i++;
           pro2 = argv[i];
        }
        else
        {
           second[i] = argv[i];
        }
        i++; 
     }
     second[i] = NULL;
     pipeit(pro1,pro2,first, second);
     return 0;
  }

In the child, you have: 孩子,你有:

    dup2(fd[1],1);
    close(fd[0]);
    close(1);

This duplicates the pipe to standard output, but then closes standard output. 这会将管道复制到标准输出,但随后关闭标准输出。 Fix by not closing standard output, and by closing both ends of the pipe. 通过不关闭标准输出并关闭管道的两端来修复。 Rule of thumb: if you duplicate one end of a pipe to standard input, output or error, you should close both of the original pipe descriptors. 经验法则:如果将管道的一端复制到标准输入,输出或错误,则应关闭两个原始管道描述符。

    dup2(fd[1],1);
    close(fd[0]);
    close(fd[1]);

You have the analogous problem in the parent with standard input being closed. 您在父级中存在类似问题,标准输入已关闭。

You also have the wait() in the wrong place. 你也有wait()在错误的地方。 The processes must run concurrently. 进程必须同时运行。 If the first process in the pipeline generates so much data that the pipe can't hold it all, the process will block. 如果管道中的第一个进程生成了大量数据,而管道无法将其全部保存,则该进程将阻塞。 If the other process is waiting for the first process to die before it reads anything, it isn't going to work well. 如果其他进程在读取任何内容之前等待第一个进程死亡,那么它将无法正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM