我想:
我使用processBuilder执行以下代码,该代码具有读取日志文件的readLog函数和执行命令的executeBash,然后销毁processbuilder的readlog进程。但是当readLog文件正在读取实时日志文件时,executeBash永远不会被调用。
如何实时读取日志文件并与executeBash同时显示?
public void performAction(OssSystem system) {
readLog(system);
executeBash(system);
}
public void executeBash(OssSystem system) {
try {
Process process = new ProcessBuilder().command("/bin/sh", system.getCommand_path(), system.getParam()).start();
BufferedReader reader
= new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
builder.append(System.getProperty("line.separator"));
}
int status = process.waitFor();
cmdResult = builder.toString() + " command status " + status;
int exitValue = process.exitValue();
readProcess.destroy();
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
String logOutput;
Process readProcess;
public void readLog(OssSystem system) {
String user = system.getUsername() + "@" + system.getIp();
String cmd = "tail -f " + system.getLog_dir() + " | less";
try {
readProcess = new ProcessBuilder().command("/usr/bin/ssh", user, cmd).start();
int status = readProcess.waitFor();
BufferedReader reader
= new BufferedReader(new InputStreamReader(readProcess.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
builder.append(System.getProperty("line.separator"));
}
logOutput = builder.toString() + " command status " + status;
} catch (IOException ex) {
Logger.getLogger(Shell.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(Shell.class.getName()).log(Level.SEVERE, null, ex);
}
}
答案 0 :(得分:1)
根据javadoc,
如果需要,导致当前线程等待,直到进程 由此Process对象表示已终止。此方法返回 如果子进程已经终止,则立即执行。如果 子进程尚未终止,调用线程将被阻塞 直到子进程退出。
因此readProcess.waitFor();
将阻塞主线程,并且在readProcess终止之前你永远不会期望调用executeBash(system);
。
您可以启动一个帖子来启动readProcess
。
public void performAction(OssSystem system) {
readLog(system);
ExecuteBashThread thread = new ExecuteBashThread(system);
thread.start();
}
class ExecuteBashThread extends Thread{
private OssSystem system;
public ExecuteBashThread(OssSystem system){
this.system = system;
}
@Override
public void run(){
executeBash(system);
}
}