java 如何使用 JSch 运行和显示 shell 命令 ssh 的结果?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16860244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to run and display the result of a shell command ssh with JSch?
提问by lopez.mikhael
I try to use the library JSch - Java Secure Channelmake an ssh connection in my Android app, it works.
我尝试使用库JSch - Java Secure Channel在我的 Android 应用程序中建立 ssh 连接,它可以工作。
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.
我尝试了几种最有效的方法是这个。但是,此方法仅部分起作用,因为出于某种原因我无法解释,我的程序在 while 循环结束时停止,但我是日志中出现的命令的结果。
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?
有没有其他人有更好的方法来使用 JSch 运行命令表?
Thank you in advance !
先感谢您 !
回答by Pa?lo Ebermann
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.
您的方法在循环中停止(而不是完成它),因为远程 shell 没有关闭输出流。没有理由这样做,因为您可以在那里发送更多命令。
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.
如果您只想执行单个命令(或之前已知的一系列命令),则不应使用 Shell 通道,而应使用“exec”通道。
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.
这样,远程 shell(执行您的命令)将在您的命令完成时完成,然后服务器将关闭流。所以你的循环将完成,然后你可以关闭流。
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.
如果你认为你需要一个 shell 通道(例如,如果你需要在同一个上下文中启动多个命令,并在决定下一个是什么之前对一个输出做出反应),你需要一些方法来知道什么时候一个命令完成(例如通过识别提示),然后发送下一个。要退出,要么关闭输出流,要么发送“注销”或“退出”命令(两者都适用于任何标准的 unix shell,其他 shell 可能需要不同的命令),然后远程站点也应该关闭另一个流。
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.
顺便说一句,虽然禁用严格的主机密钥检查很方便,但它也会打开您与中间人攻击的连接,并且在密码验证的情况下,攻击者可以获取您的密码。正确的方法是设置一个正确初始化的主机密钥存储库来识别远程主机的密钥。
回答by shaine
As far as I am aware JSch is the only real option.
据我所知,JSch 是唯一真正的选择。
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.
我发现 Jsch 错误往往需要一些挖掘。但是在第一种情况下,您将希望捕获并打印出最低限度的错误。
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
也看看网站上的示例代码