之前写过一个版本的Java代码用来调用linux shell脚本,原文如下:

http://blog.csdn.net/sheismylife/article/details/4817851


不过没有试过windows下运行,试了一下,还是不错的,把代码做了一些调整,封装成对象,这样更方便多线程下调用,不用担心静态变量互相干扰的问题。

先看一下怎么用:

    public static void main(String[] args) {
        try {
            Command command = new Command();
            CommandResult result1 = command.exec("net stop nginx", 20000);
            System.out.println("command executiion succeeds: " + result1.getOutput());
            CommandResult result2 = command.exec("net start nginx", 20000);
            System.out.println("command executiion succeeds: " + result2.getOutput());
        } catch (CommandError ex) {
            System.out.println("command execution failed: " + ex.getMessage());
        }
    }

由此可见,有三个类:Command, CommandResult和CommandError。

当命令不能运行,将会抛出CommandError异常对象。如果命令能够运行,不管是否成功或者失败,都返回CommandResult对象,里面有两个属性output和error,包含了执行成功的消息和错误消息。

CommandError.java代码:

package command;

/**
 *
 * @author shu6889
 */
public class CommandError extends Exception {

    /**
     * Creates a new instance of
     * <code>CommandError</code> without detail message.
     */
    public CommandError() {
    }

    /**
     * Constructs an instance of
     * <code>CommandError</code> with the specified detail message.
     *
     * @param msg the detail message.
     */
    public CommandError(String msg) {
        super(msg);
    }
    
    public CommandError(Throwable ex) {
        super(ex);
    }
}

CommandResult.java代码

package command;


/**
* Describe class CommandResult here.
*
*/
public class CommandResult {
 public static final int EXIT_VALUE_TIMEOUT=-1;
    
    private String output;

    void setOutput(String error) {
        output=error;
    }

    public String getOutput(){
        return output;
    }

    int exitValue;

    void setExitValue(int value) {
        exitValue=value;
    }

    int getExitValue(){
        return exitValue;
    }

    private String error;

    /**
     * @return the error
     */
    public String getError() {
        return error;
    }

    /**
     * @param error the error to set
     */
    public void setError(String error) {
        this.error = error;
    }
}

最重要的Command.java代码:

package command;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Describe class Command here.
 * 
*/
public class Command {

    private long startTime;
    private long timeout;
    private static final long INTERVAL = 500;

    /*
     * command is one system command represented by string
     * timeout is milliseconds for waiting the command execution
     * throw CommandError if the system command can't be executed
     * return CommandResult when the system command is executed no matter what the command returns(succeed or failed)
     */
    public CommandResult exec(final String command, long timeout) throws CommandError {
        this.timeout = timeout;
        try {
            Process process = Runtime.getRuntime().exec(command);
            CommandResult result = wait(process);
            if (process != null) {
                process.destroy();
            }
            return result;
        } catch (Exception ex) {
            throw new CommandError(ex);
        }
    }

    private boolean isTimeout() {
        return System.currentTimeMillis() - startTime >= timeout;
    }

    private CommandResult wait(final Process process) throws InterruptedException, IOException {
        BufferedReader errorStreamReader = null;
        BufferedReader inputStreamReader = null;
        try {
            errorStreamReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            inputStreamReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

            //timeout control
            startTime = System.currentTimeMillis();
            boolean isFinished = false;

            for (;;) {
                if (isTimeout()) {
                    CommandResult result = new CommandResult();
                    result.setExitValue(CommandResult.EXIT_VALUE_TIMEOUT);
                    result.setOutput("Command process timeout");
                    return result;
                }

                if (isFinished) {
                    CommandResult result = new CommandResult();
                    result.setExitValue(process.waitFor());

                    //parse error info
                    if (errorStreamReader.ready()) {
                        StringBuilder buffer = new StringBuilder();
                        String line;
                        while ((line = errorStreamReader.readLine()) != null) {
                            buffer.append(line);
                        }
                        result.setError(buffer.toString());
                    }

                    if (inputStreamReader.ready()) {
                        StringBuilder buffer = new StringBuilder();
                        String line;
                        while ((line = inputStreamReader.readLine()) != null) {
                            buffer.append(line);
                        }
                        result.setOutput(buffer.toString());
                    }
                    return result;
                }

                try {
                    isFinished = true;
                    process.exitValue();
                } catch (IllegalThreadStateException e) {
                    // process hasn't finished yet
                    isFinished = false;
                    Thread.sleep(INTERVAL);
                }
            }

        } finally {
            if (errorStreamReader != null) {
                try {
                    errorStreamReader.close();
                } catch (IOException e) {
                }
            }

            if (inputStreamReader != null) {
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                }
            }
        }
    }
}




Logo

更多推荐