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

标签 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 channel 监听器“等待命令执行完成”然后继续的最佳做法是什么?我可以在命令执行后使用 Thread.sleep(someTime),但出于显而易见的原因,我不太喜欢它。

最佳答案

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

您还可以看一下我自己的开源项目,该项目是我前段时间创建的,作为现有项目的继承者。它叫做ExpectIt .我的库的优点在项目主页上有说明。

这是一个使用 JSch 与公共(public)远程 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 .

关于java - 如何创建一个模拟 SSH shell 用户交互的机器人?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26102125/

相关文章:

linux - fanotify获取文件名,为什么是/proc/self/fd/"data->fd"?

bash - 由引号和未引号部分组成的字符串中的通配符扩展(通配符)

mysql - 在bash中将mysql错误写入日志文件

Linux 合并多个文件

java - 我应该使用问号类型参数还是抑制原始类型警告?

java - 来自其他类的空结果语句

java - 本地主机、开发和生产的 Spring 数据源配置

java - 如何获取 JAR 文件中资源目录中的所有资源?

linux - 将端口 80 绑定(bind)到非 root 用户。中央操作系统

linux - select调用的第一个参数是传入的要监听的fd的最大值加一