我有一个Java程序,它以交互模式执行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();
}
}
答案 0 :(得分:1)
因为标准错误和标准输出转到不同的线程,它们异步打印读取数据。如果您重定向2>&1
,它可能会有效,但我不确定它是否适用于Runtime.exec
(可能会导致“找不到文件 - 2>& 1”)。因此,您可以创建一个调用sh
并重定向其输出的shell脚本,并使用Runtime.exec
调用该脚本:
#!/bin/sh
sh -i +m 2>&1
和
Runtime.exec("customsh");