【问题标题】:Java program hangs after executing sudo su command?执行 sudo su 命令后 Java 程序挂起?
【发布时间】:2012-06-27 20:18:01
【问题描述】:

我有一个程序可以ssh 进入远程主机,然后远程执行命令。像mkdircd 这样的命令可以工作,但是当我尝试执行命令sudo su - username 时,程序就会挂起。我想知道我的代码中是否有任何遗漏/错误。

JSch jSch = new JSch();
Channel channel = null;
Session session = null;
InputStream in = null;        
String  username;
OutputStream  os  = null;;

try {   
    Properties conf = new Properties();
    conf.put("StrictHostKeyChecking", "no");

    jSch.addIdentity("id_rsa");
    jSch.setConfig(conf);
    session = jSch.getSession("username", "hostname", 22);      

    String cmd = "mkdir test";
    session.connect();   //   creating the ssh connection        

    channel = (ChannelExec) session.openChannel("exec");        
    ((ChannelExec)channel).setCommand(cmd);
    channel.setInputStream(null);
    in = channel.getInputStream(null);        
    channel.connect();  

    byte[] tmp = new byte[1024];        
    while (true) { 
        while (in.available() > 0) {
            int i = in.read(tmp, 0, 1024);
            if (i < 0) {
                break;
            }
        }
        if (channel.isClosed()) {
            break;
        }      
        try {
            Thread.sleep(1000);  // to wait for long running process ..                
        } catch (Exception ee) {
        }
        String value = new String(tmp);            
        System.out.println("input stream " + value);
    }     
}catch(Exception  e){
    e.printStackTrace();
}finally{
    channel.disconnect();
    session.disconnect();
    if(in!=null)
    in.close();
}

另外,在我sudo 之后,我需要从这个主机ssh 到另一个主机,所以基本上我需要通过网关之类的东西ssh 到远程主机,然后连接到数据库,一次这个问题得到了解决。

我们将不胜感激。

谢谢。

【问题讨论】:

  • 你有一个 catch 什么都不做,为什么不打印堆栈跟踪,因为它可能是导致“我的程序挂起”的原因,而你没有发现引发的错误
  • 程序在执行 sudo su - username 命令后就挂断了.. 任何解决方案
  • 试过了,没有抛出异常。程序不会从 while(true) 块中退出。因此,如果我插入 System.out.println("here") 语句,它会继续打印。
  • 在我看来,第一个while (true) 在这段代码中永远不会退出? break 语句只会退出内部 while 循环。

标签: java ssh channel jsch


【解决方案1】:

sudo 命令将需要 pty. 参考http://www.jcraft.com/jsch/examples/Sudo.java.html 在 exec 通道上做 sudo 和跳转主机,参考http://www.jcraft.com/jsch/examples/JumpHosts.java.html

【讨论】:

  • 我需要更改为用户部署,然后 ssh 进入下一个服务器。但是,当我执行 sudo su - username 命令时,程序不会终止。但是像 mkdir 这样的其他命令可以正常工作。所以我需要想办法先 ssh 进入 host1,然后更改为用户“用户名”,然后 ssh 进入 host2.. :(