2012-01-24 3 views
1

Я пытаюсь запустить некоторые команды unix из моего java-кода. На данный момент я использую библиотеку Expect4J от Google, и я открыт для любых хорошо документированных библиотек.Вывод команды ssh из java

Проблема в том, что я пытаюсь захватить вывод последней команды запуска, но не могу ее получить. Кто-нибудь знает, что я здесь делаю неправильно?

Проблема, которую я пытаюсь решить, заключается в подключении к моей 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. Я не уверен, что они могут быть сделаны Expect4j, так как ssh напрямую подключается к tty, чтобы задать эти вопросы. Но этот ответ, кажется, решил, что:

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 и с сервера1 на server2. Он фактически способен SSH к серверам, проблема в том, когда я передаю несуществующее имя сервера. Код по-прежнему признает, что мы вошли на сервер! – Vivek

1

Как раз идея, вы можете подумать об использовании библиотеки Java, которая обрабатывает вас и управление ключами. Вот тот, который я нашел, который, кажется, делает трюк.

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

Смотрите классы и документацию SshScript или SshSession для деталей.

+0

Да, Jscape отлично работает, как я использовал раньше. Единственная проблема - это платная библиотека, которой руководство не интересуется (по крайней мере, на данный момент). – Vivek

Смежные вопросы