![](/img/trans.png)
[英]How do I print lines from a command-line input file to a command-line output file?
[英]How do command-line interpreters work?
我一直认为操作系统上的进程有三个标准流: stdin, stdout, and stderr
。 我还认为像vim这样的文本编辑器通过在stdin
并在stdout
发送ANSI转义字符来工作。 但是,我对命令行解释器如何在这一案例中没有提到的观点如下:
当我运行命令C:\\cygwin\\bin\\bash.exe
,系统会提示我:
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\masson>C:\cygwin\bin\bash.exe
bash-3.2$
...但是当我使用以下代码片段在Java中运行它时,stdin流为空:
ProcessBuilder pb = new ProcessBuilder("C:\\cygwin\\bin\\bash.exe");
pb.redirectErrorStream(true);
Process proc = pb.start();
final InputStream in = proc.getInputStream();
new Thread(new Runnable() {
public void run() {
// Blocks forever...
in.read(new byte[1024]);
}
}).start();
这里发生了什么? 我被告知bash.exe以交互模式运行。 这是否意味着标准流未被使用? 我怎样才能继续使用这些程序,最终,我如何实现自己的cmd.exe版本? 我想我不理解命令行解释器如何工作的基本内容......
(对于讨论相关主题的文章的任何链接都将非常感激。我没有太多的运气搜索。哦,还有最后一个问题,在Windows中处理的标准流与在大多数类Unix操作系统中的处理方式不同?)
任何使用c标准库的程序都可以使用函数isatty()来判断它是否正在与tty设备(也就是命令行)进行通信。 Bash可能检测到它正在与管道而不是tty通话,并且不会输出提示。
我更像是一个Python人而不是Java人(所以我告诉你的一切都是来自JavaDoc的快速猜测),但看起来你正在设置一个多进程死锁。
in.read(new byte[1024]);
在读取1024字节数据之前不会返回,并且bash.exe
在停止等待输入之前不输出整个1024字节。 (为此,请使用proc.getOutputStream()
并为其提供一些命令以进行响应。)
结果,你得到Java等待bash响应和bash等待Java响应,并且两者完全满足于等到宇宙死亡而不会感到厌倦或厌倦。
我的建议是在每次调用in.available()
之前使用in.read()
来避免阻塞。 这样,您可以在输入数据和拉出数据之间来回切换而不会卡住。
事实上,将它包装在BufferedReader
可能会更简单和更加简洁。
从评论更新:此外,当像bash这样的工具检测到stdin不是终端(参见isatty系统调用)时,假设输入是非交互式的, 它们会以巨大的(4K或更多)块缓冲 。 我不确定它是否会有所帮助,但尝试使用-i标志启动bash。
处于交互模式并不意味着不使用标准流。 但在这种情况下,Bash最有可能以非交互模式运行(它检测到它不直接与终端应用程序通信,因此它假设它以编程方式使用,因此不会打印欢迎横幅)。 在这种情况下,仍然使用标准流,只是没有输出任何内容。
正如ergosys指出的那样,你不能真正依赖in.read(new byte[1024])
在它读取完整的1024字节之前返回,虽然可能会假设它会 - 但是,肯定不会返回在它读取至少一个字节之前,我认为这是问题 - 你甚至没有得到一个字节的输出。
尝试将“-i”传递给bash以使其以交互模式运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.