简体   繁体   中英

No correct redirection between pipes

I'm writing a program that should work like the following unix command: seq 2 number | awk argument | grep argument seq 2 number | awk argument | grep argument

#define READ 0
#define WRITE 1

void die(char* msg){
  perror(msg);
  exit(EXIT_FAILURE);
}

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

  if(pipe(seq_to_awk) == -1)
    die("pipe");

  pid_t child = fork();
  if(child == -1)
    die("fork");

  if(child == 0){
    if(close(seq_to_awk[READ]) == -1)
      die("close");

    if(dup2(seq_to_awk[WRITE], STDOUT_FILENO) < 0)
      die("dup2");

    if(close(seq_to_awk[WRITE]) == -1)
      die("close");

    execlp("seq", "seq", "2", argv[1], NULL);
  }

  child = fork();
  if(child == -1)
    die("fork");

  int awk_to_grep[2];
  if(pipe(awk_to_grep) == -1)
    die("pipe");

  if(child == 0){

    if(close(seq_to_awk[WRITE]) == -1)
      die("close");
    
    if(dup2(seq_to_awk[READ], STDIN_FILENO) < 0)
      die("dup2");

    if(close(seq_to_awk[READ]) == -1)
      die("close");
/**/
    if(close(awk_to_grep[READ]) < 0)
      die("close");

    if(dup2(awk_to_grep[WRITE], STDOUT_FILENO) < 0)
      die("dup2");

    if(close(awk_to_grep[WRITE]) == -1)
      die("close");
/**/    
    execlp("awk", "awk", argv[2], NULL);
    die("execlp");

  }

  if(close(seq_to_awk[READ]) == -1)
    die("close");
  if(close(seq_to_awk[WRITE]) == -1)
    die("close");

/**/
  child = fork();
  if(child == -1)
    die("fork");

  if(child == 0){

    if(close(awk_to_grep[WRITE]) == -1)
      die("close");

    if(dup2(awk_to_grep[READ], STDIN_FILENO) < 0)
      die("dup2");

    if(close(awk_to_grep[READ]) == -1)
      die("close");

    execlp("grep", "grep", argv[3], NULL);
    die("execlp");

  }
/**/

  if(close(awk_to_grep[READ]) == -1)
    die("close");
  if(close(awk_to_grep[WRITE]) == -1)
    die("close");

  wait(NULL);
  wait(NULL);
  wait(NULL);

  exit(EXIT_SUCCESS);
}

When I run the following code with the command: ./program 26 {print} 5 I get nothing as output, when the correct output should be:

5
15
25

I don't understand what exactly I'm doing wrong here. When I leave out one of the programs(either awk or grep) the program runs as expected.

The problem is when setting up the awk_to_grep pipe. You fork before creating the pipe, so you in fact create two separate pipes. The pipe in your child process is not available to the parent and other children created after that.

Swap the order to this:

  int awk_to_grep[2];
  if(pipe(awk_to_grep) == -1)
    die("pipe");

 child = fork();
  if(child == -1)
    die("fork");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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