【问题标题】:Prevent bash from forwarding stdin to stderr防止 bash 将标准输入转发到标准错误
【发布时间】:2012-12-07 00:05:02
【问题描述】:

我正在尝试使用 bash 的交互模式实现一个简单的终端 GUI。我成功调用了 bash,获取了它的 stdout 并将所有内容打印到文本视图中。我将用户输入从文本视图转发到 bash 的 stdin,以便能够运行命令。它工作得很好,除了我没有收到任何错误消息。

但是,当我继续将 bash 的 stderr 打印到我的文本视图时,我发现了一些奇怪的东西。除了现在接收错误消息之外,bash 似乎将所有内容从 stdin 传递到 stderr。因此,我输入的每个字符都会打印两次(通常一次是因为我输入了它,一次是因为我从 stderr 打印了所有内容)。

它似乎也通过 stderr (bash-3.2$) 打印提示。这是预期的行为吗?可以压制吗?

我还尝试只捕获使用输入(而不是让用户直接在文本视图中输入)并依靠 bash 来打印用户输入。这几乎可以正常工作,除了通过 stdoutstderr 的输出顺序是随机的:

如果我输入类似echo test 的命令并回车,有时我会得到:
(第二个test是输出,我没有输入testtest

bash-3.2$ echo testtest
bash-3.2$ 

有时我会得到:

bash-3.2$ echo test
bash-3.2$ test

我收到最后一个\n、输出和下一个bash-3.2$ 的顺序显然搞混了。

【问题讨论】:

  • 我不知道答案,但让我想起了旧的DOS @echo off
  • 你是如何调用 bash 的?我不确定您实际实施的是什么。
  • 对我来说似乎是缓冲问题。 bash 确实对 stderr 执行 stdin 回显,以便标准终端仿真器上的用户看到他正在输入的内容。您可能会在 stdout 和 stderr 上得到一些奇怪的缓冲,这会阻止您在从 bash 发送字符时立即读取它们。但是......我不知道objective-c,所以我无法为您提供更多帮助。
  • 我正在使用NSTask 来调用 bash。它允许我使用NSFileHandle 对象或 C 文件描述符来读/写 stdout/in/err。我正在尝试自己实现一个简单的终端窗口(稍后用作应用程序的一部分)。
  • @liori 我马上就能看到我输入的内容。但是,一旦我按回车键执行命令,应该按以下顺序打印 3 件事:1. \n 我刚刚通过 stderr 输入 2. 通过 stdout 输出我的命令 3. bash-3.2$ 通过 stderr。但是顺序是混乱的。是否缓冲了通过文件描述符读/写函数的 stdout/err?我会尽快阅读所有内容。

标签: objective-c c bash shell stream


【解决方案1】:

没有办法以“正确”的顺序读取 stdout 和 stderr,因为不同管道之间没有顺序的概念。但是您可以确保两者都发送到同一个管道(即相同的文件描述符),而不是让每个都发送到单独的管道。为此,请查看用于启动 bash 子进程的任何选项;或者启动一个命令行,例如bash -c 'bash 2>&1'

【讨论】:

  • 为什么我没有想到这个?...非常感谢,这似乎有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-11
  • 2011-03-24
相关资源
最近更新 更多