如何使用JSch运行并显示Shell命令ssh的结果?

4
我尝试使用库JSch - Java Secure Channel在我的Android应用程序中建立ssh连接,它可以工作。
现在我想执行一个命令并检索结果。
我尝试了几种方法,最好的是这个。然而,这个方法只部分有效,因为由于某种我无法解释的原因,我的程序在while循环结束时停止运行,但是我却在日志中看到了命令的结果。
以下是我的代码:
public static String executeRemoteCommand(String username, String password, String hostname, int port) throws Exception {     
    JSch jsch = new JSch();
    Session session = jsch.getSession(username, hostname, port);
    session.setPassword(password);

    // Avoid asking for key confirmation
    Properties prop = new Properties();
    prop.put("StrictHostKeyChecking", "no");
    session.setConfig(prop);

    session.connect();

    Channel channel = session.openChannel("shell");
    channel.connect();

    DataInputStream dataIn = new DataInputStream(channel.getInputStream());  
    DataOutputStream dataOut = new DataOutputStream(channel.getOutputStream());  

    // send ls command to the server  
    dataOut.writeBytes("ls\r\n");  
    dataOut.flush();  

    // and print the response   
    String line = dataIn.readLine();
    String result = line + "\n";

    while ((line = dataIn.readLine()) != null) {
        result += line + "\n";
        Log.i("TAG", "Line: "+line);
    }

    dataIn.close();  
    dataOut.close();  
    channel.disconnect();  
    session.disconnect();

    return result;
}

还有其他人有更好的方法来使用JSch运行命令吗?

提前感谢!

2个回答

6
你的方法在循环中停止(而不是完成它),因为远程 shell 没有关闭输出流。它没有理由这样做,因为你可以发送更多的命令。
如果你只想执行单个命令(或者已知一系列命令),你不应该使用 Shell 通道,而应该使用“exec”通道。
这样,远程 shell(执行你的命令)将在你的命令完成后完成,然后服务器将关闭该流。所以你的循环会结束,然后你可以关闭流。
如果你认为你需要一个 Shell 通道(例如,如果你需要在同一上下文中启动多个命令,并在决定下一个命令之前对其中一个命令的输出进行反应),你需要某种方式知道何时一个命令完成(例如,通过识别提示符),然后发送下一个命令。要退出,请关闭输出流或发送“logout”或“exit”命令(这两个命令都适用于任何标准 Unix shell,其他 shell 可能需要不同的命令),然后远程站点也应该关闭另一个流。
顺便说一句,虽然禁用严格的主机密钥检查很方便,但也会使你的连接面临中间人攻击,在密码身份验证的情况下,攻击者可以获取你的密码。正确的做法是设置一个正确初始化的主机密钥库,以识别远程主机的密钥。

-1
据我所知,JSch是唯一的真正选择。
我发现JSch的错误需要进行一些挖掘。但在第一时间,您至少需要捕获并打印出错误信息。
try{ 
    JSch jsch = new JSch();
    Session session = jsch.getSession(username, hostname, port);
    ... omitted 
 } catch (Exception e) {
     System.out.println(e) 
 }

同时也可以查看网站上的示例代码


谢谢您的回复,但您并没有真正回答我的问题。我试图制作一个类似于“ls”的shell命令,并且当我使用它时,我已经捕获了我的函数。 - lopez.mikhael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接