2

我正在做我的作业,即在 C 中复制 unix 命令 shell。

我已经实现了后台运行(&)的单个命令执行。

现在我正处于实现管道的阶段,我面临这个问题,对于大于 1 的管道,带有管道的子命令已完成,但最终输出不会显示在 stdout 上(最后一个命令的 stdin 被替换为 read最后一个管道)

dup2(pipes[lst_cmd], 0);

fflush(STDIN_FILENO)我也在父母那里试过。

我的程序的出口是 CONTROL-D,当我按下它时,会显示输出(也退出,因为我在 CONTROL-D 上的操作是退出(0))。

我认为管道的输出在标准输出缓冲区中,但没有显示。除了 fflush 之外,还有其他方法可以将缓冲区中的内容发送到标准输出吗?

4

1 回答 1

0

看过代码(不公平的优势)后,主要问题是流程结构与未彻底关闭管道相结合。

管道的流程结构ps | sort是:

main shell
    - coordinator sub-shell
        - ps
        - sort

主 shell 正在创建 N 个管道(N = 1 for ps | sort)。然后创建了协调器外壳;它将启动 N+1 个孩子。然而,它并没有等待它们终止,也没有关闭它的管道副本。主外壳也没有关闭它的管道副本。

更正常的流程结构可能没有协调器子外壳。有两种生成子代的机制。传统上,主 shell 会派生一个子进程;它会协调管道中的前 N ​​个进程(包括首先创建管道),然后执行管道中的最后一个进程。主 shell 等待一个子进程完成,管道的退出状态是子进程(也就是管道中的最后一个进程)的退出状态。

最近,bash提供了一种机制,通过该机制,主 shell 可以获取管道中每个子 shell 的状态;它负责协调。

主要修复(除了一些主要是次要的编译警告)是:

  1. 主壳在分叉协调器后关闭所有管道。
  2. main shell 等待协调器完成。
  3. 协调器在分叉管道后关闭所有管道。
  4. 协调器等待管道中的所有进程完成。
  5. 协调员退出(而不是返回提供决斗双重提示)。

更好的解决方法是消除协调器子外壳(它的行为类似于所描述的经典系统)。

于 2012-11-25T17:02:58.787 回答