在bash脚本中,如果我执行“内联”执行的外部程序(即“bash”)。我的意思是该进程没有跨越后台,并且子进程的stdin / stdout / stderr与bash脚本本身的stdin / stdout / stderr重合。
所以如果我的bash脚本包含
#!/bin/sh
bash
用户可以运行我的脚本,当执行bash时,他可以在bash的标准输入中键入命令,并在stdout / stderr上查看命令的结果。
这就是我的意思,即子进程是“内联”运行的。
在java中,进程跨越后台,因此Process.getOutputStream()/ Process.getInputStream()/ Process.getErrorStream不与System.in/System.out/System.err.
我想在java程序中做的是重现执行进程时发生的行为,就像上面的bash脚本示例一样。
经过一些谷歌搜索后,我推出了这个
public static void main(String[] args) throws IOException,
InterruptedException {
String[] cmdarray = {"bash"};
Process proc = Runtime.getRuntime().exec(cmdarray);
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(),
System.err);
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(),
System.out);
StreamGobbler inputGobbler = new StreamGobbler(System.in,
proc.getOutputStream());
errorGobbler.start();
outputGobbler.start();
inputGobbler.start();
int exitVal = proc.waitFor();
errorGobbler.join(); // Handle condition where the
outputGobbler.join(); // process ends before the threads finish
System.exit(exitVal);
}
class StreamGobbler extends Thread {
InputStream is;
OutputStream os;
StreamGobbler(InputStream is, OutputStream os) {
this.is = is;
this.os = os;
}
public void run() {
try {
int c;
while ((c = is.read()) != -1) {
os.write(c);
os.flush();
}
} catch (IOException x) {
throw new RuntimeException(x);
}
}
}
但是,嘿,有3个主题!加上执行过程所跨越的线程!
必须有更好的方法。类似的东西:
Runtime.execForeground("bash", System.in, System.out, System.err);
或只是:
Runtime.execForeground("bash");
执行“内联”进程,因为它适用于许多脚本语言。
也许另一种可能性是使用非阻塞I / O将stdin / stdout / stderr复制到单个线程中的System.in/out/err?任何一个例子?