How to run and display the result of a shell command ssh with JSch?

雨燕双飞 提交于 2019-12-04 13:16:07

问题


I try to use the library JSch - Java Secure Channel make an ssh connection in my Android app, it works.

Now I would like to execute a command and retrieve the result.

I tried several methods that works best is this. However, this method works only in part, because for some reason I can not explain, my program stops at the end of my while loop, yet I'm the result of the command that appears in my log.

Here is my code :

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;
}

Does anyone else have a better way to run a command sheel with JSch?

Thank you in advance !


回答1:


Your method stops in the loop (instead of finishing it) because the remote shell doesn't close the output stream. It has no reason to do this, since there you could send more commands.

If you only want to execute a single command (or a series of commands known before), you shouldn't use a Shell channel, but an "exec" channel.

This way the remote shell (which executes your command) will finish when your command is finished, and then the server will close the stream. So your loop will finish, and then you can close the streams.

If you think you need a shell channel (for example, if you need to fire up multiple commands in the same context, and react to one's output before deciding what would be the next one), you'll need some way to know when one command is finished (e.g. by recognizing the prompt), and then send the next one. To quit, either close the output stream or send a "logout" or "exit" command (both work with any standard unix shell, other shells might need different commands), then the remote site should close the other stream, too.

By the way, while disabling strict host key checking is convenient, it also opens up your connection to a man-in-the-middle attack, and in case of password authentication, the attacker can grab your password. The right way to do this would be to set up a correctly initialized host key repository to recognize the remote host's key.




回答2:


As far as I am aware JSch is the only real option.

I have found that Jsch errors tend to take some digging. But in the first instance you will want to catch and print out the errors as a minimum.

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

also have a look a the example code on the site



来源:https://stackoverflow.com/questions/16860244/how-to-run-and-display-the-result-of-a-shell-command-ssh-with-jsch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!