我有一个问题,我尝试从 java 代码运行一个 sh 文件来启动 JBoss 服务器,所以当我执行这个 sh 文件时,我想知道它何时启动并打印出我的控制台。这是我的代码:
public static void runStart() {
try {
String command = "./Run.sh";
String s = get_commandline_results(command);
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("done");
}
public static String get_commandline_results(String cmd)
throws IOException, InterruptedException, IllegalCommandException {
String result = "";
Process p = null;
p = Runtime.getRuntime().exec(String.format("bash -c %s", cmd));
final ProcessResultReader stderr = new ProcessResultReader(
p.getErrorStream(), "STDERR");
final ProcessResultReader stdout = new ProcessResultReader(
p.getInputStream(), "STDOUT");
System.out.println("starting...");
stderr.start();
stdout.start();
final int exitValue = p.waitFor();// It was delayed here because sh not complete
System.out.println("started!");// How to go to here?
if (exitValue == 0) {
result = stdout.toString();
} else {
result = stderr.toString();
}
return result;
}
}
class ProcessResultReader extends Thread {
final InputStream is;
final String type;
final StringBuilder sb;
ProcessResultReader(final InputStream is, String type) {
this.is = is;
this.type = type;
this.sb = new StringBuilder();
}
public void run() {
try {
final InputStreamReader isr = new InputStreamReader(is);
final BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
this.sb.append(line).append("\n");
}
} catch (final IOException ioe) {
System.err.println(ioe.getMessage());
throw new RuntimeException(ioe);
}
}
@Override
public String toString() {
return this.sb.toString();
}
}
感谢您的帮助!
最佳答案
您的目标相互矛盾:您希望不等待脚本终止(即您希望 JBoss 运行)而继续,但与此同时,您希望知道结果。除非 build 时间机器,否则这是不可能的。
您可以做的是在另一个脚本 start.sh
中启动脚本:
#!/bin/bash
nohup base -c ./Run.sh > /dev/null &
注意:您可以通过使 Run.sh
可执行来省略 bash -c
。
此脚本将作为后台进程启动 Run.sh
并立即退出。但是,如果 JBoss 无法启动,您将不会收到错误消息,因为稍后会发生这种情况。
这个难题的一个解决方案是一个脚本,它读取 JBoss 的日志文件几秒钟,或者直到它看到一行文本,这意味着“JBoss 已成功启动”。
为此,使用启动脚本,然后在 Java 代码中,开始读取 JBoss 的日志文件(您可能需要先等待它出现)。
对于这种技巧,在尝试启动 JBoss 之前先删除旧日志文件总是好的。否则,Java 程序可能会读取旧日志文件并继续,而 JBoss 仍在尝试开始写入新日志。
关于java - 如何在没有等待结果的情况下执行 sh 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18492059/