在 sshj 中执行命令的 sequense

2022-09-05 00:19:22

我需要使用sshj库通过ssh在远程服务器上执行一些命令序列。

我愿意

        Session session = ssh.startSession();
        Session.Command cmd = session.exec("ls -l");
        System.out.println(IOUtils.readFully(cmd.getInputStream()).toString());
        cmd.join(10, TimeUnit.SECONDS);
        Session.Command cmd2 = session.exec("ls -a");
        System.out.println(IOUtils.readFully(cmd2.getInputStream()).toString());

它扔了我

net.schmizz.sshj.common.SSHRuntimeException:这个会话通道全部用完了

但是我无法为每个命令重新创建会话,因为此示例将显示主目录列表,但不会显示 /some/dir 列表。


答案 1

尽管它很奇怪,但只能使用一次。因此,您每次都必须重置会话。session

    Session session = ssh.startSession();
    Session.Command cmd = session.exec("ls -l");
    System.out.println(IOUtils.readFully(cmd.getInputStream()).toString());
    cmd.join(10, TimeUnit.SECONDS);

    session = ssh.startSession();
    Session.Command cmd2 = session.exec("ls -a");
    System.out.println(IOUtils.readFully(cmd2.getInputStream()).toString());

或者,如果您要连接到的 shell 支持分隔命令(并且情况允许),则可以执行此操作(bash 示例):

session.exec("ls -l; <command 2>; <command 3>");


答案 2

您可以考虑使用类似 Expect 的第三方库,它简化了使用远程服务并捕获输出的过程。这些库旨在执行一系列命令。以下是您可以尝试的一组很好的选项:

但是,当我准备解决类似的问题时,我发现这些库相当古老。它们还引入了许多不需要的依赖项。所以我创建了自己的,并把它提供给其他人。它被称为ExpectIt。我的库的优势在项目主页上说明。你可以试一试。

下面是使用 sshj 与公共远程 SSH 服务交互的示例:

    SSHClient ssh = new SSHClient();
    ...
    ssh.connect("sdf.org");
    ssh.authPassword("new", "");
    Session session = ssh.startSession();
    session.allocateDefaultPTY();
    Shell shell = session.startShell();
    Expect expect = new ExpectBuilder()
            .withOutput(shell.getOutputStream())
            .withInputs(shell.getInputStream(), shell.getErrorStream())
            .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();
    }

以下是指向完整可行示例的链接。


推荐