2016-02-21 98 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也放在一个忙碌的循环之前