【发布时间】:2012-02-09 15:35:59
【问题描述】:
我正在尝试用 Java 实现终端仿真器。它应该能够在 Windows 上托管 cmd.exe 并在类 Unix 系统上托管 bash(我希望至少支持 Linux 和 Mac OS X)。我遇到的问题是 cmd.exe 和 bash 在他们的标准输出上重复我发送到他们的标准输入的任何内容。
例如,在 bash 中,我键入“ls”,按回车键,此时终端仿真器将输入行发送到 bash 的标准输入并刷新流。然后该进程再次输出输入行“ls\n”,然后输出ls 命令。
这是一个问题,因为除了bash 和cmd.exe 之外的其他程序不这样做。如果我在 bash 或 cmd.exe 中运行命令“python -i”,python 交互式 shell 不会像 bash 和 cmd.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