0

我有一个问题,我尝试从 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();
    }
}

感谢您的帮助!

4

1 回答 1

2

You have contradicting goals here: You want to continue without waiting for the script to terminate (i.e. you want JBoss running) but at the same time, you want to know the result. Short of building a time machine, this is impossible.

What you can do is you can start the script within another script start.sh:

#!/bin/bash

nohup base -c ./Run.sh > /dev/null &

Note: You can omit bash -c by making Run.sh executable.

This script will start Run.sh as a background process and exit immediately. But if JBoss can't start, you won't get an error since that will happen later.

One solution for this dilemma is a script that reads the log files of JBoss for a couple of seconds or until it sees a line of text that means "JBoss has started successfully".

To do that, use the start script and then in the Java code, start reading the log file of JBoss (you may need to wait for it to show up, first).

For this kind of trick, it's always good when you delete the old log files first, before you try to start JBoss. Otherwise, the Java program might read an old log file and continue while JBoss is still trying to start writing a new log.

于 2013-08-28T15:30:46.430 回答