简体   繁体   中英

Execution of UNIX command is being outputted after I exit the program

For some unknown reason, when I'm executing piped commands in my shell program, they're only outputting once I exit the program, anyone see why?

Code:

int execCmdsPiped(char **cmds, char **pipedCmds){

  // 0 is read end, 1 is write end 
  int pipefd[2]; 

  pid_t pid1, pid2; 

  if (pipe(pipefd) == -1) {
    fprintf(stderr,"Pipe failed");
    return 1;
  } 
  pid1 = fork(); 
  if (pid1 < 0) { 
    fprintf(stderr, "Fork Failure");
  } 

  if (pid1 == 0) { 
  // Child 1 executing.. 
  // It only needs to write at the write end 
    close(pipefd[0]); 
    dup2(pipefd[1], STDOUT_FILENO); 
    close(pipefd[1]); 

    if (execvp(pipedCmds[0], pipedCmds) < 0) { 
      printf("\nCouldn't execute command 1: %s\n", *pipedCmds); 
      exit(0); 
    }
  } else { 
    // Parent executing 
    pid2 = fork(); 

    if (pid2 < 0) { 
      fprintf(stderr, "Fork Failure");
      exit(0);
    }

    // Child 2 executing.. 
    // It only needs to read at the read end 
    if (pid2 == 0) { 
      close(pipefd[1]); 
      dup2(pipefd[0], STDIN_FILENO); 
      close(pipefd[0]); 
      if (execvp(cmds[0], cmds) < 0) { 
        //printf("\nCouldn't execute command 2...");
        printf("\nCouldn't execute command 2: %s\n", *cmds);
        exit(0);
      }
    } else {
      // parent executing, waiting for two children
      wait(NULL);
    } 
  }
}

Output:

例如,当我输入“ls | sort -r”时程序的输出

In this example of the output, I have used "ls | sort -r" as the example, another important note is that my program is designed to only handle one pipe, I'm not supporting multi-piped commands. But with all that in mind, where am I going wrong, and what should I do to fix it so that it's outputting within the shell, not outside it. Many thanks in advance for any and all advice and help given.

The reason would be your parent process file descriptors are not closed yet. When you wait for the second command to terminate, it hangs because the writing end is not closed so it wait until either the writing end is closed, or new data is available to read.

Try closing both pipefd[0] and pipefd[1] before waiting for process to terminate.

Also note that wait(NULL); will immediately return when one process has terminated, you would need a second one as to not generate zombies if your process still runs after that.

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