2010-08-03 106 views
1

目标:远程控制具有一个连接和多个会话或一个永久会话的ssh服务器。Java和SSH:保持连接

问题1:我目前使用sshj通过SSH做一些远程控制,它运行良好,但我似乎无法正确处理提示。 (主机不提供真正的根,只是sudo -i,所以我需要先登录)。 问题2:我下载了ExpectJ来处理提示,但是我无法为我的生活找出一旦我登录并以root身份进行身份验证后如何维护会话。

目前哈克解决方案要求我重新登录每次:

public class Expect { 
    Spawn shell; 
    ExpectJ exp; 
    String host; 
    int port; 
    String username; 
    String passwd; 
    boolean sudo = false; 
    public Expect(String host,int port,String username,String passwd) throws IOException, TimeoutException, ExpectJException{ 

     exp = new ExpectJ(5); 
     this.host = host; 
     this.port = port; 
     this.username = username; 
     this.passwd = passwd; 
     shell = exp.spawn(host, port, username, passwd); 
     shell.send("sudo netstat -natvp | grep Xtightvnc\n"); 
     System.out.println(shell.getCurrentStandardOutContents()); 
     try{ 
      shell.expect("[sudo] password for #######:"); 
      shell.send(passwd+"\n"); 
     } 
     catch (IOException ex){ 
      String err = ex.toString(); 
      if(!err.equals("java.io.IOException: End of stream reached, no match found")){ 
       throw new IOException(ex); 
      } 
     } 
    } 

问题1:可以sshj用于“预期”密码提示?我找不到任何文件暗指这种类型的控制。

Quetsion 2:如何修改上述Expect代码以维护一个可以进行多次调用的持久连接?我希望能够继续进行交互,一旦我达到了以root身份进行身份验证的状态,但一旦初始命令已发送,Spawn就会始终关闭。

回答

1

问题1:可以用sshj来“期待”密码提示吗?我找不到任何文件暗指这种类型的控制。

sshj提供的主要是shell或命令的I/O流的句柄,以及获取诸如退出状态之类的东西的方法。

问题2:我如何修改上面的Expect代码来维护一个可以进行多次调用的持久连接?我希望能够继续进行交互,一旦我达到了以root身份进行身份验证的状态,但一旦初始命令已发送,Spawn就会始终关闭。

支持通过单个SSH连接进行并发会话,甚至并发会话。但请注意,一个shell /命令/子系统只能有一个会话。

您正在使用哪种Session,即Session.Shell(通过session.startShell)或Session.Command(通过session.exec)?在后一种情况下,一旦完成执行命令,会话就是,意思是关闭,这是预期的行为。

通常不会推荐Shell而不是Command,但由于你装备了ExpectJ,我猜可以处理提示等,你可能想要去那个路线。如果字符等回显存在问题,请使用PTY选项(而不是session.allocateDefaultPTY调用session.allocatePTY,这需要大量的参数,请看source for allocateDefaultPTY)。

代码示例:ShellCommand

另外,如果您缩小问题到与sshj的错误,不要在这个问题上跟踪汇报:)