【问题标题】:Terminal emulator implementation - problems with repeated input终端仿真器实现 - 重复输入的问题
【发布时间】:2012-02-09 15:35:59
【问题描述】:

我正在尝试用 Java 实现终端仿真器。它应该能够在 Windows 上托管 cmd.exe 并在类 Unix 系统上托管 bash(我希望至少支持 Linux 和 Mac OS X)。我遇到的问题是 cmd.exebash 在他们的标准输出上重复我发送到他们的标准输入的任何内容。

例如,在 bash 中,我键入“ls”,按回车键,此时终端仿真器将输入行发送到 bash 的标准输入并刷新流。然后该进程再次输出输入行“ls\n”,然后输出ls 命令。

这是一个问题,因为除了bashcmd.exe 之外的其他程序不这样做。如果我在 bash 或 cmd.exe 中运行命令“python -i”,python 交互式 shell 不会像 bashcmd.exe 那样重复输入。这意味着解决方法必须知道实际输出来自哪个进程。我怀疑这就是实际的终端模拟器所做的。

运行“bash -i”不会改变这种行为。据我所知,cmd.exe 没有明显的“交互”和“非交互”模式。


编辑:我正在使用ProcessBuilder 类创建主机进程。我正在读取标准输出和标准错误,并使用类似于stream gobbler 的技术写入进程的标准输入。在启动主机进程之前,我没有设置任何环境变量。我用来启动进程的确切命令是 bash -i 用于 bash 和 cmd 用于 cmd.exe。一旦我设法创建一个,我将尝试发布最小的代码示例。

【问题讨论】:

  • 这似乎与bash 相关:隐藏用户输入。 tech-recipes.com/rx/278/… 不过,不确定它的便携性。
  • 这很有趣,echo ls | bash 不要做那样的事情。
  • 在unix中,可以使用stty -echo命令关闭回显。您可以在 Windows 上使用一些 ansi 序列,但是(1)我不记得它是什么; (2) 你不能保证 ansi.sys 会出现在目标系统上。
  • 在windows上可以调用cmd.exe,带有/c参数,意思是“执行以下命令并退出”。不确定这是否能解决您的问题。
  • @Honza 交互式 Windows 控制台程序在连接到一对管道而不是实际的控制台窗口时通常无法正常工作。例如,它使它们默认为完全缓冲和特定于控制台的 API 调用,例如更改颜色将失败。麻烦的是,MS 没有提供允许完全替换内置控制台的“伪控制台”界面。你能做的最好的事情就是console.sf.net 所做的:拥有一个隐藏的控制台窗口并使用 ReadConsoleOutput() API 获取其屏幕内容。显然,这与您在 Unix 上需要做的非常不同。

标签: bash shell terminal cmd terminal-emulator


【解决方案1】:

在 Unix 上,运行 stty -echo 以禁用“本地回显”(即 shell 重复您键入的所有内容)。这通常是启用的,因此用户可以编辑她键入的内容。

在你的情况下,BASH 必须以某种方式分配一个伪 TTY;否则,它不会回显每个命令。 set +x 会产生类似的效果,但是您会在输出中看到 + ls 而不是 ls

使用cmd.exe 命令@ECHO OFF 应该可以达到相同的效果。

只需在进程创建后执行它们,它应该可以工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-29
    • 2015-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    相关资源
    最近更新 更多