java - 如何在没有等待结果的情况下执行 sh 文件?

标签 java linux runtime.exec

我有一个问题,我尝试从 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/

相关文章:

java - 如何使用弹出窗口中的另一个按钮创建一个按钮

java - 'java.lang.NullPointerException' 错误的未知来源

linux - DBeaver/PostgresQL 无法连接到远程 docker 容器

linux - 如何为 GIT 存储库中的文件创建符号链接(symbolic link)

java - java中的cleartool命令执行-runtime().exec

java - RESTEASY 如何让@PathParam 匹配一个UUID?

java - 我的教授在 setter 中跳过了一个变量,他在编写的代码中是否犯了错误?

linux - 如何grep美元符号($)?

Java 运行时 exec() 行为

java - Java中的FFMPEG(运行时错误)