2013-11-26 63 views
1

我在使用JSch的遠程計算機上運行shell腳本,並使用JSch通道在我的日誌文件中打印命令日誌。問題是,當腳本結束時,我執行channel.disconnect並斷開連接後,System.out停止打印到日誌文件中。下面是代碼:JSch channel.disconnect防止打印日誌

private int runShellScript(HashMap bundleDetails) { 
     int exitStatus = -1; 
     Channel channel = null; 
     Session session = null; 
     try { 
      java.util.Properties config = new java.util.Properties(); 
      config.put("StrictHostKeyChecking", "no"); 

      String host = (String) bundleDetails.get("host"); 
      String userName = (String) bundleDetails.get("userName"); 
      String password = (String) bundleDetails.get("password"); 
      String bundleName = findFileName((String) bundleDetails.get("bundleName")); 

      String sourceLocation = (String) bundleDetails.get("sourceLocation"); 
      String logFileName = findFileName((String) bundleDetails.get("logFileName")); 

      String targetLocation = (String)bundleDetails.get("targetLocation");    

      String command1 = "sh "+(String) bundleDetails.get("targetIndexerLocation") + (String) bundleDetails.get("deployScript")+" "+ 
            targetLocation + bundleName + " " + 
            targetLocation + logFileName; 
      JSch ssh = new JSch(); 
      session = ssh.getSession(userName, host, 22); 
      session.setConfig(config); 
      session.setPassword(password); 
      session.connect(); 

      channel = session.openChannel("exec"); 
      ((ChannelExec)channel).setCommand(command1); 
      channel.setInputStream(null); 
      ((ChannelExec)channel).setErrStream(System.err); 
      InputStream in=channel.getInputStream(); 
      channel.connect(); 
      byte[] tmp=new byte[1024]; 
      while(true){ 
       //System.out.println("inside while second"); 
        while(in.available()>0){ 
        int i=in.read(tmp, 0, 1024); 
        if(i<0)break; 
        System.out.print("*****NEW ONE*****$$$$$**$$########"+new String(tmp, 0, i)); 
       } 
        if(channel.isClosed()){ 
         exitStatus = channel.getExitStatus(); 
        System.out.println("Before Disconnected Here exit-status: "+exitStatus); 
         channel.disconnect(); 
        System.out.println("Disconnected Here exit-status: "+exitStatus); 
        break; 
        } 
      }  
      //logger("runShellScript", "END"); 
      System.out.println("***** out of infinite loop"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      throw new RuntimeException("Copy to remote location failed.... "); 
     }finally{ 
      System.out.println("finally DISCONNECT channel and session"); 
      if(channel!=null && channel.isConnected()){ 
       channel.disconnect(); 
      } 
      if(session!=null){ 
       session.disconnect(); 
      }   
      System.out.println("finally DISCONNECTED channel and session"); 

     } 
     System.out.println("Before return exit-status: "+exitStatus); 
     return exitStatus; 
    } 

從日誌文件中的行:

*****NEW ONE*****$$$$$**$$########Starting... 

斷開這裏退出狀態前:0

如果你在我上面粘貼的方法見,所打印的sysout實際上就是'channel.disconnect'之上的那個。下面的那個不打印!人的運作是正確的,整體輸出是什麼,我希望

的System.out.println(「以前這裏斷開退出狀態: 」 +退出狀態);
channel.disconnect();
System.out.println(「Disconnected Here exit-status:」+ exitStatus);

所有的功能是正確的,總體產出是我所期望的。唯一的問題是日誌凍結。我哪裏錯了?

編輯
此外,我無法看到從我的最後塊堵塞!

回答

2

最有可能是涉及到這一行:

((ChannelExec)channel).setErrStream(System.err); 

通過這樣做,你已經追平了System.err的流通道流。根據文檔,默認情況下,當通道斷開連接時,流將關閉。你不會說你在運行什麼平臺,但我認爲大多數平臺都以某種方式連接System.err和System.out,所以Jsch很可能會在斷開連接時關閉System.out。您可能會嘗試這樣做是爲了防止JSch從關閉流:

((ChannelExec)channel).setErrStream(System.err, true); 

Javadoc

即使,它的工作,雖然,我覺得到System.err的掛鉤像這是一個有點冒險。我認爲更安全的設計是創建一個直接寫入日誌文件的流,而不是通過System.err。

+0

WOW!完美無缺地工作。喘氣我錯過了它。感謝一噸kaliatech的快速反應。肯定會應用你的建議! – Adi

0

這是因爲

((ChannelExec)channel).setErrStream(System.err); 

而且當你正在斷開通道,連接流也被切斷。

所以,請斷開通道之前寫如下的語句:

((ChannelExec)channel).setErrStream(null);