【问题标题】:Execution of UNIX command is being outputted after I exit the program退出程序后正在输出UNIX命令的执行
【发布时间】:2020-02-06 04:20:08
【问题描述】:

由于某些未知原因,当我在我的 shell 程序中执行管道命令时,它们只有在我退出程序后才输出,有人知道为什么吗?

代码:

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);
    } 
  }
}

输出:

在这个输出示例中,我使用了“ls | sort -r”作为示例,另一个重要说明是我的程序设计为只处理一个管道,我不支持多管道命令。但是考虑到所有这些,我哪里出错了,我应该怎么做才能修复它,以便它在 shell 内输出,而不是在 shell 之外。非常感谢您提供的任何和所有建议和帮助。

【问题讨论】:

  • 您从哪里得到这样的想法,即一次调用wait 会等待多个孩子?也许您将wait 系统调用与wait shell 命令混淆了,如果没有给出参数,它会等待所有子进程。
  • 自从我很久以前就停止使用wait 并且没有考虑它的语义,我真的不知道如果你调用wait 两次会发生什么。也许它会立即第二次返回有关同一个孩子的信息。与时俱进(即 90 年代中期)并使用 waitpid。

标签: c shell pipe stdout stdin


【解决方案1】:

原因可能是您的父进程文件描述符尚未关闭。当您等待第二个命令终止时,它会挂起,因为写入端未关闭,因此它会等到写入端关闭或有新数据可供读取。

在等待进程终止之前尝试关闭pipefd[0]pipefd[1]

另请注意,wait(NULL); 将在一个进程终止时立即返回,如果您的进程在此之后仍然运行,您将需要第二个以不生成僵尸。

【讨论】:

  • 它们都已关闭,不是吗,还是您的意思是我应该在dup2()'d 之前关闭它们?
  • 您确实在子进程中关闭了它们,但对父进程没有这样做。正如答案中所说,在等待之前尝试关闭两者。
  • 哦!对不起,菜鸟的错误汗水加剧,这完全解决了问题,非常感谢:D
猜你喜欢
  • 1970-01-01
  • 2019-12-05
  • 2017-05-14
  • 2012-01-03
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
相关资源
最近更新 更多