问题描述
我有一个远程GNU / Linux系统上从Java SSH上执行命令的麻烦。当本地的Bash(当然用户和主机是不同的,但行为是不变)。
I am having trouble executing commands on a remote GNU/Linux system over SSH from Java. The following commands work fine when executed in the local Bash (of course the user and host are different but the behaviour is unchanged).
$ ssh user@host.example.com 'hostname'
host
$ ssh user@host.example.com 'hostname -f'
host.example.com
$ ssh user@host.example.com "hostname -f"
host.example.com
在做我觉得是一样从Java失败不带参数的事情要复杂得多主机名
。
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.Executor;
import org.apache.commons.exec.PumpStreamHandler;
public class SOPlayground {
public static void main(String[] args) throws Exception {
for (String argument : new String[]{"hostname", "'hostname'", "\"hostname\"",
"'hostname -f'", "\"hostname -f\""}) {
CommandLine commandLine = new CommandLine("ssh");
commandLine.addArgument("user@host.example.com");
commandLine.addArgument(argument);
System.out.println(commandLine);
final Executor executor = new DefaultExecutor();
try (ByteArrayOutputStream os = new ByteArrayOutputStream();
ByteArrayOutputStream err = new ByteArrayOutputStream()) {
executor.setStreamHandler(new PumpStreamHandler(os, err));
int exitcode = executor.execute(commandLine);
System.out.println("exitcode=" + exitcode);
System.out.println(new String(os.toByteArray(), "UTF-8"));
System.err.println(new String(err.toByteArray(), "UTF-8"));
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
}
}
输出是:
ssh user@host.example.com hostname
exitcode=0
host
ssh user@host.example.com 'hostname'
exitcode=0
host
ssh user@host.example.com "hostname"
exitcode=0
host
ssh user@host.example.com 'hostname -f'
Process exited with an error: 127 (Exit value: 127)
ssh user@host.example.com "hostname -f"
Process exited with an error: 127 (Exit value: 127)
正如你所看到的,在执行主机名-f
在从Java SSH失败,127退出code不知什么的庆典(本地或远程)是无法找到的什么的命令。
As you can see, executing hostname -f
over SSH from Java fails with an exit code of 127. I wonder what bash (local or remote) was unable to find what command.
我试图使用变量
addArgument(String argument, boolean handleQuoting)
但有在结果没有差别。
but there was no difference in the result.
我如何必须建立一个的CommandLine
从Java的作品通过SSH?
How must I build a CommandLine
from Java that works over SSH?
推荐答案
您可以使用JSch以公钥认证方式。
You can use JSch with publickey authentication.
如果你只想使用 EXEC
来执行单个远程命令,然后关闭连接,在这里你有一个工作的例子:
If you only want to use exec
to execute a single remote command and then closes the connection, here you have a working example:
public static void main(String[] args) {
String user = "--";
String host = "--";
try
{
JSch jsch = new JSch();
// key authentication
jsch.addIdentity("id_rsa");
// open a new session on port 22
Session session = jsch.getSession(user, host, 22);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
String command = "ls /";
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
StringBuilder sb = new StringBuilder();
byte[] tmp = new byte[1024];
while (true)
{
while (in.available() > 0)
{
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
sb.append(new String(tmp, 0, i));
}
if (channel.isClosed())
{
if (in.available() > 0)
continue;
System.out.println("exit-status: "
+ channel.getExitStatus());
break;
}
try
{
Thread.sleep(500);
}
catch (Exception ee)
{
}
}
//disconnecting and closing
channel.disconnect();
session.disconnect();
System.out.println("Output: ");
System.out.println(sb.toString());
}
catch (Exception e)
{
//something should be done here
e.printStackTrace();
}
}
输出:
exit-status: 0
Output:
1
bin
boot
cgroup
dev
etc
home
lib
lib64
lost+found
....
希望它能帮助
请注意: id_rsa
是路径的密钥文件
Note: id_rsa
is the path to the key file
这篇关于在从Java SSH执行bash命令的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!