【问题标题】:Managing stdout/stdin when writing a Linux shell编写 Linux shell 时管理 stdout/stdin
【发布时间】:2014-09-08 03:21:04
【问题描述】:

我正在做一个学校项目,虽然不是必需的,但我想实现这个功能。话虽如此,我无法共享代码,但我认为在这种情况下这无关紧要。

在使用fork()时,我的理解是创建的子进程继承了stdin和stdout,因为子进程继承了父进程的所有文件流。

我的 shell 需要后台功能,虽然它在技术上已经具备,但如果“后台”程序运行,它仍然会从标准输入接收所有数据并继续输出到屏幕,这只是一团糟。作为记录,我的讲师编译的示例 shell 做了同样的事情,但我不希望这种情况发生!

我很确定我应该使用 pipe()、fork() 和 dup2() 的组合,但我不能把它们放在一起。我了解 fork,但我不了解 pipe 或 dup2 的工作原理以及我应该如何在 shell 中实现它。我在想一些事情:

thePipe[2] = pipe();
pid = fork();
close stdin/out on child somehow if backgrounded

但我不明白 pipe() 或 dup2() 的功能,所以我被卡住了。

谢谢!

【问题讨论】:

  • 如果我的理解正确,您可能会想对终端(termcap 或 terminfo?)做一些事情,如果可能的话,告诉它生成 SIGTTIN 和/或 SIGTTOU job control signals。自从我研究这个以来已经有一段时间了,所以很遗憾我无法提供实际的答案。
  • 阅读Advanced Linux Programming;它很好地解释了如何使用pipe(7)-s
  • Shell 总是以这种方式工作,后台进程继续写入标准输入和标准输出,就像前台进程一样。全面抑制这种情况在外壳中不是可取的行为。您想要的是(1)一个不写入任何标准流的程序;或 (2) 在运行时重定向后台程序的标准流。
  • 请参阅 man 2 pipeman 2 dup 以更好地了解未命名的管道和 dup。如果你想了解命名管道那么你也可以参考man 2 mknod

标签: c linux bash shell


【解决方案1】:

你不想要这里的管道。在交互式 shell 中运行的进程应该与 shell 共享它们的标准文件描述符——否则会破坏更多的东西(包括子进程确定它们正在交互式运行的能力,以及与 tty 交互以处理诸如窗口之类的事情的能力大小变化)。它还会使管道严重复杂化。不要这样做。

这里缺少的部分是进程组,它在 Open Group UNIX 规范的"General Terminal Interface" 部分中进行了描述。简而言之,可以使内核显式识别终端的“前台进程组”。如果不在该组中的进程尝试读取或写入终端,则会自动停止。

作为 GNU libc 手册的一部分,"Implementing a Job Control Shell" 下提供了制作正常运行的 shell 所需的简要介绍。尝试按照他们的说明进行操作,看看效果如何。

【讨论】:

  • 非常感谢。这是自项目完成以来我没有时间跟进的另一件事,现在我们又分配了另一件事。我会在不久的将来修改我们的外壳。现在项目已经完成,截止日期已过,我将代码公开:github.com/ccs19/sysnet1p1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-19
  • 2011-10-01
  • 2013-06-14
  • 2016-07-09
  • 1970-01-01
  • 2012-12-04
  • 1970-01-01
相关资源
最近更新 更多