2016-08-30 4 views
0

私がしようとしています:私は、ログ・ファイルを読み込むreadLog機能を持っていたProcessBuilderを使用してコードを次しているProcessBuilderをモニターリモートサーバにログファイル

bashスクリプト

  • 読むログファイルを実行コマンドを実行した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

    のjavadocによると、

    は、必要に応じて現在のスレッドがプロセスまで、待機させこのProcessオブジェクトが表す0が終了しました。サブプロセスがすでに終了している場合、このメソッドはすぐに を返します。 サブプロセスがまだ終了していない場合、サブプロセスが終了するまで、呼び出しスレッドはブロック になります。

    ので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); 
        } 
    } 
    
    +0

    tail -fが終了していないため、どの例であれ非常に便利です。 – kinkajou

    +0

    @kinkajouアップデートをご覧ください。 – Gearon

    +0

    しかし、読み取りログはbashの実行をブロックしているので、最初にbashを実行しないでください。 – kinkajou

    関連する問題