processbuilder监视远程服务器

时间:2016-08-30 15:18:45

标签: java

我想:

  1. 执行Bash脚本
  2. 阅读日志文件
  3. 我使用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);
        }
    }
    

1 个答案:

答案 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);
    }
}