1

I don't know if this is plausible or desired by others, but...

Using JSch and API, I have had no success understanding it all.

When you connect with a Session to create a shell Channel and send a command and wait for it to finish, is there a way to detect or get notified that the job has finished?

Three solutions would be acceptable: 1) Get a notification (signal, event, other) 2) Read a flag (boolean, exit status, other) 3) Read the output real-time and parse for a completion statement

Here's is the template I have been using:

    import java.io.ByteArrayInputStream;
    import java.io.InputStream;

    import com.jcraft.jsch.Channel;
    import com.jcraft.jsch.JSch;
    import com.jcraft.jsch.JSchException;
    import com.jcraft.jsch.Session;

    /** Demonstrates a connection to a remote host via SSH. **/
    public class ExecuteSecureShellCommand
    {
      private static final String user = ""; // TODO: Username of ssh account on remote machine
      private static final String host = ""; // TODO: Hostname of the remote machine (eg: inst.eecs.berkeley.edu)
      private static final String password = ""; // TODO: Password associated with your ssh account
      private static final String command = "ls -l\n"; // Remote command you want to invoke

      public static void main(String args[]) throws JSchException, InterruptedException
      {
        JSch jsch = new JSch();

        // TODO: You will probably want to use your client ssl certificate instead of a password
        // jsch.addIdentity(new File(new File(new File(System.getProperty("user.home")), ".ssh"), "id_rsa").getAbsolutePath());

        Session session = jsch.getSession(user, host, 22);

        // TODO: You will probably want to use your client ssl certificate instead of a password
        session.setPassword(password);

        // Not recommended - skips host check
        session.setConfig("StrictHostKeyChecking", "no");

        // session.connect(); - ten second timeout
        session.connect(10*1000);

        Channel channel = session.openChannel("shell");

        // TODO: You will probably want to use your own input stream, instead of just reading a static string.
        InputStream is = new ByteArrayInputStream(command.getBytes());
        channel.setInputStream(is);

        // Set the destination for the data sent back (from the server)
        // TODO: You will probably want to send the response somewhere other than System.out
        channel.setOutputStream(System.out);

        // channel.connect(); - fifteen second timeout
        channel.connect(15 * 1000);

        // Wait three seconds for this demo to complete (ie: output to be streamed to us).
        Thread.sleep(3*1000);

        // Disconnect (close connection, clean up system resources)
        channel.disconnect();
        session.disconnect();
      }
    }
donkon
  • 909
  • 9
  • 23
  • I'd suggest taking the advice in the `TODO` comment about not just dumping everything to `System.out`. Instead you'll want to get the data sent from the remote host as an `InputStream`. By reading from the stream, you should be able to determine when you are connected, when the job has finished processing, and when the connection has been closed. – aroth Mar 24 '14 at 02:12
  • So, that is what I don't know how to do. I have found this [about not reading from output](http://stackoverflow.com/questions/18029609/how-can-we-read-or-use-the-contents-of-outputstream). So, channel.getInputStream() ? – donkon Mar 24 '14 at 02:17
  • Yes, `channel.getInputStream()` is what you want. Here's a good example that uses it to retrieve a file off the remote host: http://www.jcraft.com/jsch/examples/ScpFrom.java.html – aroth Mar 24 '14 at 02:19

0 Answers0