如何创建模拟SSH shell用户交互的机器人?

时间:2014-09-29 14:20:25

标签: java linux shell ssh jsch

我试图实现一个模拟用Java编写/读取ssh控制台的用户的机器人。 我正在使用JSCH库来管理ssh连接。 这是我开始的代码:

JSch jsch = new JSch();
Session session = jsch.getSession(username, ipAddress, port);
session.setPassword(password);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect(connectionTimeoutInMillis);
Channel channel = session.openChannel("shell");
InputStream is = new InputStream();
OutputStream out= new OutputStream();
channel.setInputStream(is);
channel.setOutputStream(out);
channel.connect();
channel.disconnect();
is.close();
out.close();
session.disconnect();

显然代码中的InputStreamOutputStream是错误的,我需要使用机器人可以用来发送字符串(命令行)并接收字符串(结果为命令执行),我应该用什么类型的流来获取它?

此外我注意到,如果我发送命令并在许多情况下使用System.out作为输出流,则输出为空,因为(我几乎可以肯定这一点)Java应用程序在命令之前终止执行产生了结果。告诉JSCH通道监听器" 等待命令执行完成的最佳做法是什么"然后继续?在命令执行后我可以使用Thread.sleep(someTime),但由于显而易见的原因,我不太喜欢它。

1 个答案:

答案 0 :(得分:1)

考虑使用第三方Expect-like Java库来简化与远程shell的交互。您可以尝试以下一组很好的选项:

您还可以查看我之前创建的自己的开源项目,作为现有项目的继承者。它被称为ExpectIt。我的库的优点在项目主页上说明。

以下是使用JSch与公共远程SSH服务进行交互的示例。根据您的使用情况应该很容易采用它。

    JSch jSch = new JSch();
    Session session = jSch.getSession("new", "sdf.org");
    session.connect();
    Channel channel = session.openChannel("shell");

    Expect expect = new ExpectBuilder()
            .withOutput(channel.getOutputStream())
            .withInputs(channel.getInputStream(), channel.getExtInputStream())
            .withErrorOnTimeout(true)
            .build();
    try {
        expect.expect(contains("[RETURN]"));
        expect.sendLine();
        String ipAddress = expect.expect(regexp("Trying (.*)\\.\\.\\.")).group(1);
        System.out.println("Captured IP: " + ipAddress);
        expect.expect(contains("login:"));
        expect.sendLine("new");
        expect.expect(contains("(Y/N)"));
        expect.send("N");
        expect.expect(regexp(": $"));
        expect.send("\b");
        expect.expect(regexp("\\(y\\/n\\)"));
        expect.sendLine("y");
        expect.expect(contains("Would you like to sign the guestbook?"));
        expect.send("n");
        expect.expect(contains("[RETURN]"));
        expect.sendLine();
    } finally {
        session.close();
        ssh.close();
        expect.close();
    }

以下是指向完整可行的example

的链接