2012-01-24 6 views
1

Java 코드에서 유닉스 명령을 실행하려고합니다. 나는 현재 Google의 Expect4J 라이브러리를 사용하고 있으며 잘 문서화 된 라이브러리를 공개하고 있습니다.Java에서 ssh 명령 출력을 캡쳐하십시오.

문제는 마지막으로 실행 한 명령의 출력을 캡처하려고하지만이를 가져올 수 없다는 것입니다. 아무도 모르는가, 내가 여기서 뭘 잘못하고 있니?

내가 여기에서 해결하려고 노력하는 문제는 연결이 가능하면 대상 서버에 일부 스크립트를 복사하거나 실행해야하는 기반으로 내 jumphost에 연결 한 다음 SSH를 다른 서버에 연결하는 것입니다.

내가 작성한 코드는 아래에 붙여 넣습니다. 도와주세요 !!!

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Hashtable; 
import java.util.List; 

import org.apache.oro.text.regex.MalformedPatternException; 
import org.junit.internal.matchers.SubstringMatcher; 

import com.jcraft.jsch.ChannelShell; 
import com.jcraft.jsch.JSch; 
import com.jcraft.jsch.Session; 
import com.bean.Server; 

import expect4j.Closure; 
import expect4j.Expect4j; 
import expect4j.ExpectState; 
import expect4j.matches.Match; 
import expect4j.matches.RegExpMatch; 

public class ExpectTest1 { 

    public final String RETURN_CHAR = "\r "; 
    public String expectOut = ""; 

    private StringBuilder sBuilder = new StringBuilder(); 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     Expect4j exp; 
     List<String> cmdsToRun = new ArrayList<String>(); 

     try { 
      ExpectTest1 test = new ExpectTest1(); 
      exp = test.SSH("jumpbox.xyz.com","user1","passwd", cmdsToRun); 
      exp.getLastState().toString(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
    } 


} 

    public Expect4j SSH(String hostname, String username, String password, List<String> cmdsToRun) throws Exception { 
     return SSH(hostname, username, password, 22, cmdsToRun); 
    } 

    public Expect4j SSH(String hostname, String username, String password, int port, List<String> cmdsToRun) throws Exception { 

    JSch jsch=new JSch(); 
    Session session=jsch.getSession(username, hostname, port); 
    if(password != null) { 
     session.setPassword(password); 
    } 

    Hashtable config=new Hashtable(); 
    config.put("StrictHostKeyChecking", "no"); 
    session.setConfig(config); 
    session.setDaemonThread(true); 
    session.connect(3 * 1000); // making a connection with timeout. 

    ChannelShell channel = (ChannelShell) session.openChannel("shell"); 

    channel.setInputStream(System.in); 
    channel.setOutputStream(System.out); 

    channel.setPtyType("vt102"); 

    Expect4j expect = new Expect4j(channel.getInputStream(), channel.getOutputStream()); 

    channel.connect(5*1000); 

    Server hostServer = new Server(); 
    hostServer.setHostName("box1.xyz.com"); 
    hostServer.setUsername("user2"); 

    Server destServer = new Server(); 
    destServer.setHostName("box2.xyz.com"); 
    destServer.setUsername("user3"); 

    boolean isLogged = doSSH(hostServer, expect); 
    if(isLogged) { 
     doSSH(destServer, expect); 
    } 

    return expect; 
} 

    private boolean doSSH (Server server, Expect4j expect) throws IOException, MalformedPatternException, Exception { 
     String command = "ssh " + server.getUsername() + "@" + server.getHostName() + RETURN_CHAR; 
     System.out.println("Logging in to: " + command); 
     boolean logged; 
     expect.send(command); 
     Thread.sleep(4000); 
     command = "uname -a" + RETURN_CHAR; 
     System.out.println(command); 
     expect.send(command); 
     Thread.sleep(10000); 

      if(isMatch(expect,server.getHostName().substring(0,server.getHostName().indexOf(".")))) { 
      System.out.println("Logged in to:" + server.getHostName() + "....."); 
      return true; 
     } 

     if(isMatch(expect, "Last login")) { 
      System.out.println("Logged in to:" + server.getHostName() + "....."); 
      return true; 
     } 

     if(isMatch(expect, "not known")) { 
      System.out.println("Node or Service not known..."); 
      return false; 
     } 

     System.out.println("Node or Service not known..."); 
     return false; 

     /*expect.expect(new Match[] { 
      new RegExpMatch("Name or service not known", new Closure() { 
       public void run(ExpectState state) throws Exception { 
        System.out.println("Name or service not known..."); 
        expectOut = state.getBuffer(); 
      } 
     }) 
     }); 

     expect.expect(new Match[] { 
       new RegExpMatch("Last login: \\w{3} (.*) from", new Closure() { 
        public void run(ExpectState state) throws Exception { 
         System.out.println("Logged In...."); 
         expectOut = state.getBuffer(); 
        } 
       }) 
      }); 

     if(expectOut != null && expectOut.length()>0 && !expectOut.matches("Name or service not known")) 
      return true; 

     return false;*/ 

    } 

    private boolean isMatch(Expect4j expect, String regEx) throws MalformedPatternException, Exception { 
     /*expect.expect(new Match[] { 
       new RegExpMatch(regEx, new Closure() { 
        public void run(ExpectState state) throws Exception { 
         System.out.println(state.getBuffer()); 
         System.out.println(state.getMatch()); 
         expectOut = state.getMatch(); 
         //System.out.println(state.getMatch()); 
        } 
       }) 
      }); 

     if(expectOut != null 
       && expectOut.length()>0 
       && expectOut.matches(regEx)) { 
      //System.out.println(regEx); 
      return true; 
     }*/ 
     System.out.println("*************"); 
     System.out.println(expect.expect(regEx)); 
     System.out.println("*************"); 
     if(expect.expect(regEx) == 0) 
      return true; 

     return false; 
    } 

}

답변

1

나는 당신의 ssh 명령이 암호를 요청하려고 또는`에서 known_hosts 파일에 호스트 키를 추가하도록 요구하기 위해 노력하고 있다고 생각한다. 나는 ssh가 그 질문을하기 위해 직접 tty에 연결하기 때문에 Expect4j가 그걸 할 수 있는지 확신하지 못한다. 그러나이 대답은 해결 한 것 같다 그것은 :

Using expect to pass a password to ssh

여기에 도움이 될 수 비슷한 질문/답변입니다 : 내가

How to make a ssh connection to a firewall(router) with java?

을 자동화하고 내 ssh 연결, 나는 암호 대신 공개/개인 키 암호화를 사용하여 서버에 연결하고 서버가 암호없이 성공적으로 명령 행에서 클라이언트에 연결되었는지 확인하십시오. 전체 호스트 이름이인지 확인하십시오. 이렇게하면 호스트 키가`known_hosts '파일에 저장되므로 나중에 알려줄 수 없습니다.

+0

답변 해 주셔서 감사합니다. jumphost에서 server1로 그리고 server1에서 server2로 암호를 덜 설정했습니다. 그것은 실제로 서버에 SSH 수 있습니다, 문제는 내가 존재하지 않는 서버 이름을 전달할 때입니다. 코드는 여전히 우리가 서버에 로그온했음을 인식합니다 !! – Vivek

1

생각해 보니 기대와 키 관리를 처리하는 Java 라이브러리를 사용하는 것이 좋습니다. 여기 트릭을하는 것으로 보이는 하나가 있습니다.

http://www.jscape.com/products/components/java/ssh-factory/

은 자세한 내용은 SshScript 또는 SshSession 클래스와 설명서를 참조하십시오.

+0

예, Jscape는 이전 버전과 마찬가지로 잘 작동합니다. 경영자가 실제로 관심이없는 유료 도서관에만 문제가 있습니다 (적어도 현재로서는). – Vivek

관련 문제