execute sequense of commands in sshj

烂漫一生 提交于 2019-11-29 03:57:15

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.

As odd as it is, session can only be used once. So you have to reset the session every time.

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

Or if the shell you are connecting to supports delimited commands (and the situation allows it), you can do this (bash example):

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

This question is old but just to clarify, quoting from the wiki https://github.com/hierynomus/sshj/wiki

Session objects are not reusable, so you can only have one command/shell/subsystem via exec(), startShell() or startSubsystem() respectively. But you can start multiple sessions over a single connection.

In our case we have made put it in a function

public String runCmd(SSHClient sshClient, String command) throws IOException  {
    String response = "";

    try (Session session = sshClient.startSession()) {
        final Command cmd = session.exec(command);
        response = (IOUtils.readFully(cmd.getInputStream()).toString());
        cmd.join(5, TimeUnit.SECONDS);
        // System.out.println("\n** exit status: " + cmd.getExitStatus());
    } 
    return response;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!