【问题标题】:How to run and display the result of a shell command ssh with JSch?如何使用 JSch 运行和显示 shell 命令 ssh 的结果?
【发布时间】:2013-05-27 10:47:32
【问题描述】:

我尝试使用库 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 运行命令表吗?

提前谢谢你!

【问题讨论】:

    标签: java android shell jsch


    【解决方案1】:

    您的方法在循环中停止(而不是完成它),因为远程 shell 没有关闭输出流。 它没有理由这样做,因为您可以发送更多命令。

    如果您只想执行单个命令(或之前已知的一系列命令),则不应使用 Shell 通道,而应使用“exec”通道。

    这样远程shell(执行你的命令)将在你的命令完成时完成,然后服务器将关闭流。这样你的循环就会结束,然后你就可以关闭流了。

    如果你认为你需要一个 shell 通道(例如,如果你需要在同一个上下文中启动多个命令,并在决定下一个命令是什么之前对一个输出做出反应),你需要一些方法来知道一个命令何时完成(例如通过识别提示),然后发送下一个命令。要退出,关闭输出流或发送“logout”或“exit”命令(两者都适用于任何标准的 unix shell,其他 shell 可能需要不同的命令),然后远程站点也应该关闭另一个流。

    顺便说一句,虽然禁用严格的主机密钥检查很方便,但它也会打开您与中间人攻击的连接,并且在密码验证的情况下,攻击者可以获取您的密码。正确的做法是设置一个正确初始化的主机密钥库来识别远程主机的密钥。

    【讨论】:

      【解决方案2】:

      据我所知,JSch 是唯一真正的选择。

      我发现 Jsch 错误往往需要一些挖掘。但在第一种情况下,您至少需要捕获并打印出错误。

      try{ 
          JSch jsch = new JSch();
          Session session = jsch.getSession(username, hostname, port);
          ... omitted 
       } catch (Exception e) {
           System.out.println(e) 
       }
      

      也可以看看site上的示例代码

      【讨论】:

      • 感谢您的回复,但您并没有真正回答我的问题。我试着做一个像“ls”这样的sheel命令,当我使用它时我已经抓住了我的功能。
      猜你喜欢
      • 1970-01-01
      • 2011-01-25
      • 2015-06-28
      • 1970-01-01
      • 2017-03-19
      • 2015-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多