【问题标题】:stdin/stdout for command launched from a shell用于从 shell 启动的命令的标准输入/标准输出
【发布时间】:2014-11-10 10:43:14
【问题描述】:

一个关于输入终端时回显字符的基本问题。

以一个 Linux 系统为例,cat 命令是从 shell(例如 bash)发出的。现在,据我了解,shell 生成了一个执行 cat 可执行文件的进程,并且在此阶段, cat stdin 和 stdout 已附加到终端。

现在的问题是:shell 是继续从终端接收字符(最终回显它们)还是只接收生成的进程(执行 cat)?

【问题讨论】:

    标签: linux shell


    【解决方案1】:

    shell 会将文件描述符 (fd's) 传递给子进程 (cat),但也会转移控制权。因此,只要cat 正在运行,shell 就不会做任何事情,不会接收输入,等等。

    从技术上讲,shell forks 和 execs 是子 fork 中的子进程,然后是 waits 以​​完成子进程。完成后,shell 将等待更多输入(允许您键入下一个命令),然后运行,等等。

    【讨论】:

      【解决方案2】:

      前台进程接收来自终端的输入。无论哪个进程在前台都是唯一接收它的进程(除非它包含将其传递给另一个进程的内部逻辑)。

      【讨论】:

        【解决方案3】:

        shell 不接收字符,只接收前台进程。但这还不是全部。

        您键入的内容首先由终端设备驱动程序处理。驱动程序有两种工作模式:规范和非规范。在运行cat 时使用的规范模式下,驱动程序会在您键入字符时回显字符并累积文本行。这允许进行一些基本的编辑,例如使用退格键删除您输入的内容。 cat 在您按下回车键或 Ctrl-D 之前无法看到您输入的内容。

        在非规范模式下,终端只是将字符传递给进程而不进行解释或修改:这就是全屏应用程序的工作方式。

        【讨论】:

          【解决方案4】:

          感谢回复,

          我做了一个“实验”,强制关闭终端(腻子)本地回声。将 cat 启动到 shell 并发送我可以看到的字符

          ~ # 猫

          你好

          你好

          ~#

          对于我输入的每个字符('h' 'e' 'l' 'l' 'o'),我可以在终端屏幕上看到每个字符,然后按回车键,我可以看到整个单词“hello”。

          现在,IUUC,屏幕上出现的第一个字符是由于“规范模式”终端设备驱动程序(驱动程序回显它们)。然后就在我点击 Return 时,累积的行 'hello' 被 cat “看到”并从它发送到标准输出(再次是终端屏幕)

          有意义吗?

          【讨论】:

          • 是的,这完全有道理。正如您所注意到的:单独字符的回显是由您的本地终端引起的。程序cat 以行缓冲模式启动(默认情况下),所以一旦你按回车,它就会看到你的“你好”。然后,如果您使用 ^D 退出 cat,shell 将接收您接下来键入的任何内容。
          • 这里的“本地终端”是指终端设备驱动程序(例如 /dev/pty/0)而不是终端 Putty 软件?
          • 既然你写了你强迫 Putty 进入本地回显模式,这就是我的意思。当我窥探 libc 调用 read 返回的内容及其调用方式时,我看到 Bash 一个一个请求字符,但我看到 cat 处于行缓冲模式;所以read 被要求获得更长的缓冲区。在我的情况下 (MacOSX) cat 要求 read 从 fd 0 (stdin) 获取 131072 个字符; read 然后返回看到 6 个字符(你好加上换行符)。如果您想窥探此类 libc 调用:我已在 kubat.nl/pages/blogaria/310 上发表了一篇简短的博文。
          • 也许我不清楚,但是关于本地回显模式,Putty(在另一台 PC 上运行)被强制关闭
          • 啊,情节变厚了。很抱歉错过了。在这种情况下,我只能将单个字符视为由 Linux 机器上的设备驱动程序回显的解释。我想不出别的了;因为事实上,cat 只会在您按 Enter 后看到您的 hello 而不会在之前看到;所以cat 本身永远无法回显单独的字符。
          猜你喜欢
          • 2014-02-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-24
          • 2021-04-29
          • 2010-09-13
          • 2013-09-18
          • 1970-01-01
          相关资源
          最近更新 更多