Piyush Vinchurkar
Piyush Vinchurkar

Reputation: 17

Efficiently execute multiple commands that depend on another long running command on Unix host with JSch

I need to execute commands on remote SSH server in Java. I'm using JSch for that.

A Command 1 is a command to setup an environment on Linux machine and which requires some time to execute (about 20 minutes). Command 1 is a one time operation. If I open a PuTTY session I need to execute the Command 1 only once.

A Command 2 dependents on the Command 1. It does not execute without the Command 1.

Once the Command 1 is executed (one time operation), the Command 2 (requires 2-3 seconds to execute) can be executed for different entities without the Command 1 being executed again.

I know I can do it with commands separated by &&, but in that way the Command 1 will execute unnecessarily degrading overall performance.

Code:

String host = "1.1.1.1";
String user = "parag";
String password = "abcdf";
String command1 = "command1";
String command2 = "command2";
try {

    java.util.Properties config = new java.util.Properties();
    config.put("StrictHostKeyChecking", "no");
    JSch jsch = new JSch();
    Session session = jsch.getSession(user, host, 22);
    session.setConfig(config);
    session.setPassword(password);
    session.connect();
    System.out.println("Connected");

    Channel channel = session.openChannel("exec");
    ((ChannelExec) channel).setCommand(command1 + " && " + command2);
    channel.setInputStream(null);
    ((ChannelExec) channel).setErrStream(System.err);

    InputStream in = channel.getInputStream();
    channel.connect();
    byte[] tmp = new byte[1024];
    while (true) {
        while (in.available() > 0) {
            int i = in.read(tmp, 0, 1024);
            if (i < 0)
                break;
            System.out.print(new String(tmp, 0, i));
        }
        if (channel.isClosed()) {
            System.out.println("exit-status: " + channel.getExitStatus());
            break;
        }
        try {
            Thread.sleep(1000);
        } catch (Exception ee) {
        }
    }
    channel.disconnect();
    session.disconnect();
    System.out.println("DONE");
} catch (Exception e) {
    e.printStackTrace();
}

Please let me know if this is possible. Also suggest an alternative if any, in case this is not possible with JSch.

Upvotes: 1

Views: 526

Answers (1)

Martin Prikryl
Martin Prikryl

Reputation: 202222

What you have now is the correct way.

If you really really need to optimize it, you have to feed the commands to a remote shell session. Either start a shell explicitly using the "exec" channel. Or use "shell" channel directly. And then write the individual commands to the shell input.

See also:


Obligatory warning: Do not use StrictHostKeyChecking=no to blindly accept all host keys. That is a security flaw. You lose a protection against MITM attacks. For the correct (and secure) approach, see: How to resolve Java UnknownHostKey, while using JSch SFTP library?

Upvotes: 1

Related Questions