在从Java SSH执行bash命令的问题 [英] Problems executing Bash command over SSH from Java

查看:665
本文介绍了在从Java SSH执行bash命令的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个远程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命令的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆