之前写过一个版本的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
* CommandError
without detail message.
*/
public CommandError() {
}
/**
* Constructs an instance of
* CommandError
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) {
}
}
}
}
}