Java 为什么子流程的输出顺序错误?
我有一个Java程序,它以交互模式作为子进程执行Java 为什么子流程的输出顺序错误?,java,linux,process,stream,Java,Linux,Process,Stream,我有一个Java程序,它以交互模式作为子进程执行sh。输入从System.in复制,输出复制到System.out。除了在这个交互式shell中运行诸如pwd之类的命令时,输出以错误的顺序显示外,其他一切都正常工作,例如: $ pwd $ /home/viz/workspace 而不是 $ pwd /home/viz/workspace $ 不同之处在于,在第一种情况下,提示$在pwd的输出之前打印 你知道为什么会发生这种情况以及如何解决吗 代码如下: import java.io.IOEx
sh
。输入从System.in
复制,输出复制到System.out
。除了在这个交互式shell中运行诸如pwd
之类的命令时,输出以错误的顺序显示外,其他一切都正常工作,例如:
$ pwd
$ /home/viz/workspace
而不是
$ pwd
/home/viz/workspace
$
不同之处在于,在第一种情况下,提示$
在pwd
的输出之前打印
你知道为什么会发生这种情况以及如何解决吗
代码如下:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
class StreamCopier implements Runnable {
private InputStream in;
private OutputStream out;
public StreamCopier(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
}
public void run() {
try {
int n;
byte[] buffer = new byte[4096];
while ((n = in.read(buffer)) != -1) {
out.write(buffer, 0, n);
out.flush();
}
out.close();
}
catch (IOException e) {
System.out.println(e);
}
}
}
public class Test {
public static void main(String[] args)
throws IOException, InterruptedException {
Process process = Runtime.getRuntime().exec("sh -i +m");
Thread outThread = new Thread(new StreamCopier(
process.getInputStream(), System.out));
outThread.start();
Thread errThread = new Thread(new StreamCopier(
process.getErrorStream(), System.err));
errThread.start();
Thread inThread = new Thread(new StreamCopier(
System.in, process.getOutputStream()));
inThread.start();
process.waitFor();
outThread.join();
errThread.join();
inThread.join();
}
}
因为标准错误和标准输出会转到不同的线程,这些线程异步打印读取的数据。如果重定向
2>&1
,它可能会工作,但我不确定它是否适用于Runtime.exec
(可能会导致“找不到文件-2>&1”)。因此,您可以创建一个shell脚本,该脚本调用sh
并重定向其输出,然后使用Runtime.exec
调用该脚本:
#!/bin/sh
sh -i +m 2>&1
及
如果你运行一个不同的shell会发生什么?@dacwe:到目前为止,我只能让
sh
工作。尝试了bashbash
,但在尝试执行IO时它被停止。可能它需要一些其他选项(+m
没有帮助)。但是$
和/home/viz/workspace
都应该在标准输出上输出吗?(所以这里没有比赛.)@dacwe no.从命令行sh1>temp.log
尝试,然后键入pwd
。您将看到命令行提示符,但不会看到pwd输出,它将转到temp.log
。很好!然后是vitaut解决方案!
Runtime.exec("customsh");