javasshsshj

execute sequense of commands in sshj


I need to execute some sequence of commands at the remote server via ssh, using sshj library.

I do

        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());

and it throws me

net.schmizz.sshj.common.SSHRuntimeException: This session channel is all used up

But I can't recreate session for every single command, because this example it will show home directory list, but not the /some/dir list.


Solution

  • You can consider using an Expect-like third party library which simplifies working with remote services and capturing output. Those libraries are designed to execute a sequence of commands. Here is a good set of options you can try:

    However, when I was about to solve similar problem I found these libraries are rather old. They also introduce a lot of unwanted dependencies. So I created my own and made it available for others. It is called ExpectIt. The advantages of my library it are stated on the project home page. You can give it a try.

    Here is an example of interacting with a public remote SSH service using sshj:

        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();
        }
    

    Here is the link to the complete workable example.