Shell 类功能:
是一个提供执行操作系统命令的类,主要有两个抽象方法给基类去继承,
1.abstract String[] getExecString(); 继承类实现该方法,提供一个要给shell在执行的命令
2. abstract void parseExecResult(BufferedReader lines) 继承类实现该方法,Shell执行命令后把结果给该方法去解释
3.shell 类只是提供一个shell命令执行的总体框架,具体的框架实现由下面方法实现:
/** Run a command */
private void runCommand() throws IOException {
// 创建一个进程,参数从执行命令,从继承类的抽象方法取得
ProcessBuilder builder = new ProcessBuilder(getExecString());
Timer timeOutTimer = null;
ShellTimeoutTimerTask timeoutTimerTask = null;
timedOut = new AtomicBoolean(false);
completed = new AtomicBoolean(false);
if (environment != null) {
builder.environment().putAll(this.environment);
}
if (dir != null) {
builder.directory(this.dir);
}
process = builder.start();
if (timeOutInterval > 0) { // 如果有设超时时间, 设一个定时任务,超时时会调用它,去终止process
timeOutTimer = new Timer("Shell command timeout");
timeoutTimerTask = new ShellTimeoutTimerTask(
this);
//One time scheduling.
timeOutTimer.schedule(timeoutTimerTask, timeOutInterval);
}
// 设置 java builder process 的错误返回流
final BufferedReader errReader =
new BufferedReader(new InputStreamReader(process
.getErrorStream()));
// 设置 java builder process 的标准返回流
BufferedReader inReader =
new BufferedReader(new InputStreamReader(process
.getInputStream()));
final StringBuffer errMsg = new StringBuffer();
// read error and input streams as this would free up the buffers
// free the error stream buffer
Thread errThread = new Thread() {
@Override
public void run() {
try {
String line = errReader.readLine();
while((line != null) && !isInterrupted()) {
errMsg.append(line);
errMsg.append(System.getProperty("line.separator"));
line = errReader.readLine();
}
} catch(IOException ioe) {
LOG.warn("Error reading the error stream", ioe);
}
}
};
// 读错误输出流
try {
errThread.start();
} catch (IllegalStateException ise) { }
// 读标准输出流
try {
parseExecResult(inReader); // parse the output
// clear the input stream buffer
String line = inReader.readLine();
while(line != null) {
line = inReader.readLine();
}
// wait for the process to finish and check the exit code
exitCode = process.waitFor(); // chb 超时返回0
try {
// make sure that the error thread exits
errThread.join(); // chb 让读错误返回流的进程结束
} catch (InterruptedException ie) {
LOG.warn("Interrupted while reading the error stream", ie);
}
completed.set(true);
//the timeout thread handling
//taken care in finally block
if (exitCode != 0) {
throw new ExitCodeException(exitCode, errMsg.toString());
}
} catch (InterruptedException ie) {
throw new IOException(ie.toString());
} finally {
// chb 最后完成时,取消定时任务, 关闭输入流,关闭错误读取线程
if (timeOutTimer != null) {
timeOutTimer.cancel(); // chb 如果正常执行完,取消定时任务
}
// close the input stream
try {
inReader.close();
} catch (IOException ioe) {
LOG.warn("Error while closing the input stream", ioe);
}
if (!completed.get()) {
errThread.interrupt();
}
try {
errReader.close();
} catch (IOException ioe) {
LOG.warn("Error while closing the error stream", ioe);
}
process.destroy();
lastTime = System.currentTimeMillis();
}
}
ProcessBuilder类相关知识介绍请google!