Executing Interactive Commands within a Remote Shell

Introduction

One of the difficulties with any Java SSH API is how to execute commands interactively. The SSH session is just a stream of characters so how does an API determine when a command starts and finishes, and what is command interpreter output?

With the Maverick Synergy Java SSH API we have solved this with the ExpectShell implementation. With ExpectShell you can execute commands over a Java SSH connection, filtering the output of each command for processing, wait for completion and obtain the exit code of commands run in the interactive shell.

Source Code

package examples;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.sshtools.client.SessionChannelNG;
import com.sshtools.client.SshClient;
import com.sshtools.client.shell.ExpectShell;
import com.sshtools.client.shell.ShellTimeoutException;
import com.sshtools.client.tasks.ShellTask;
import com.sshtools.common.ssh.SshException;
import com.sshtools.common.util.Utils;

public class Shell {

   public static void main(String[] args) throws IOException {

      try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
			
         String hostname = Utils.prompt(reader, "Hostname", "localhost");
         int port = 22;
         if (Utils.hasPort(hostname)) {
            port = Utils.getPort(hostname);
         }

         String username = Utils.prompt(reader, "Username", System.getProperty("user.name"));
         String password = Utils.prompt(reader, "Password");

         try (SshClient ssh = new SshClient(hostname, port, username, password.toCharArray())) {

            ssh.runTask(new ShellTask(ssh) {
               @Override
               protected void onOpenSession(SessionChannelNG session)
                      throws IOException, SshException, 
                                   ShellTimeoutException {

                  ExpectShell shell = new ExpectShell(this);

                  shell.execute("mkdir tmp");
                  shell.execute("cd tmp");
                  shell.execute("echo Synergy was here > readme.txt");
                  shell.execute("tar czf package.tar.gz readme.txt");
                  shell.execute("chmod 600 package.tar.gz");
               }
            });

            ssh.disconnect();
         }

      } catch (IOException | SshException e) {
         System.out.println(e);
      }
   }
}