2016-02-21 97 views
0

Jsch在shell模式下我想按順序執行命令。我嘗試使用下面的代碼。代碼的問題是代碼在readLine()上等待。任何人都可以提出解決方案。如果可以,請修復下面的代碼JSCH執行並按順序打印命令輸出

注:我想執行的shell模式命令只

public class SSHClient1 { 

    private Session session; 
    private ChannelShell channel; 
    private String username = ""; 
    private String password = ""; 
    private String hostname = ""; 

    public SSHClient1(String username, String password, String hostname) throws Exception { 
     super(); 
     this.username = username; 
     this.password = password; 
     this.hostname = hostname; 
     startSession(); 
     intializeChannel(); 
    } 

    private void startSession() throws Exception{ 
     if(session == null || !session.isConnected()){ 
      session = connect(hostname,username,password); 
     } 
    } 

    private void intializeChannel() throws Exception{ 
     if(channel == null || !channel.isConnected()){ 
      try{ 
       channel = (ChannelShell)session.openChannel("shell"); 
       channel.setPty(false); 
       channel.connect(); 
      }catch(Exception e){ 
      } 
     } 
    } 

    private Session connect(String hostname, String username, String password) throws Exception{ 
     JSch jSch = new JSch(); 
     try { 
      session = jSch.getSession(username, hostname, 22); 
      Properties config = new Properties(); 
      config.put("StrictHostKeyChecking", "no"); 
      session.setConfig(config); 
      session.setPassword(password); 
      session.connect(); 
      System.out.println("Connected successfully to host "+ hostname); 
     }catch(Exception e){ 
     } 
     return session; 
    } 

    public void executeCommands(List<String> commands) throws Exception{ 
     PrintStream out = null; 
     try{ 
      out = new PrintStream(channel.getOutputStream()); 
      for(String command : commands){ 
       out.println(command); 
       out.flush(); 
       printResult(); 
      } 

     }catch(Exception e){ 
     } finally{ 
      if(out != null) 
       out.close(); 

     } 
    } 

    private void printResult() throws IOException{ 
     try{ 
      InputStream in = channel.getInputStream(); 
      String line = ""; 
      BufferedReader br =new BufferedReader(new InputStreamReader(in)); 
      while((line = br.readLine()) != null){ 
       System.out.println(line); 
      } 
     }catch(Exception e){ 
     } 

    } 


    public void close(){ 
     if(channel != null) 
      channel.disconnect(); 
     if(session != null) 
      session.disconnect(); 
    } 


    public static void main(String[] args) throws Exception{ 

     SSHClient1 ssh = new SSHClient1("admin", "password", "192.168.2.9"); 
     List<String> commands = new ArrayList<String>(); 
     commands.add("enable"); 
     commands.add("configure terminal"); 
     commands.add("show running-config"); 
     ssh.executeCommands(commands); 
     ssh.close(); 

    } 
} 

如果我改變了上面的代碼我能實現我想要的兩種方法該方法的問題是我需要在創建緩衝區之後放置一個Thread.sleep,否則它不會打印任何東西。

public void executeCommands(List<String> commands) throws Exception{ 
     PrintStream out = null; 
     try{ 
      out = new PrintStream(channel.getOutputStream(),true); 
      for(String command : commands){ 
       out.println(command); 
       out.flush(); 
       printResult(); 
      } 
     }catch(Exception e){ 
     } finally{ 
      if(out != null) 
       out.close(); 

     } 
    } 

    private void printResult() throws IOException{ 
     try{ 
      InputStream in = channel.getInputStream(); 
      BufferedReader br =new BufferedReader(new InputStreamReader(in)); 
      Thread.sleep(10000); 
      boolean ready = false; 
      int c = 0; 
      StringBuilder line = new StringBuilder(); 
      while((ready = br.ready()) == true){ 
       ready = br.ready(); 
       c = br.read(); 
       System.out.print(String.valueOf((char)c)); 
      } 
     }catch(Exception e){ 
     } 
    } 

回答

1

如果包裹的命令是一個選項,你可以這樣做:

# cat /usr/bin/your-enable 
#!/bin/bash 
enable 
echo "#END#" 

變化主要(例如):

commands.add("/usr/bin/your-enable"); 

變化printResult:

while((line = br.readLine()) != null){ 

    if (line.equals("#END#")) { 
     break; 
    } else { 
     System.out.println(line); 
    } 
} 

希望它有助於。

+0

Yair在我的情況下是不可能的。 –

+0

所以你可以添加一個新命令來分隔你的命令:「echo」#END#「」並在printResult中使用相同的代碼。在閱讀之前,你必須每次發送2個命令。 –

+0

我不在linux機器上工作。它是一個啓用ssh的路由器,它只有很少的命令。其次在我的情況br.readLine本身暫停 –

0

能夠找到解決方案。在br.ready()爲true的情況下放置了一個繁忙的旋轉。我們需要把一個Thread.sleep也放在一個忙碌的循環之前