Send command via ssh and read ouput results

Quochg picture Quochg · Dec 13, 2013 · Viewed 7.9k times · Source

I have code to connect to a remote server via ssh and send 2 or more commands to it (for example: cd /export/home/ops/bin and "./viewlinkload –time 20131205-19") but I don't see the command executed and don't receive results.

I need to get the result returned from server and display it.

This is code send command:

try {
    command = "cd /export/home/ops/bin";
    command1="./viewlinkload –time 20131205-19";

    session.startShell();
session.getOutputStream().write(command.getBytes());
        ChannelInputStream in = session.getInputStream();
        ChannelOutputStream out = session.getOutputStream();
        InputStream inputStream = session.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(
            new InputStreamReader(inputStream));
        StringBuilder stringBuilder = new StringBuilder();
        String line;

        while ((line = bufferedReader.readLine()) != null) {
            stringBuilder.append(line);
            stringBuilder.append('\n');
        }
        System.out.println("ke qua" + stringBuilder.toString());
        // return stringBuilder.toString();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

If i Change command is "ls\n" After the last record is suspend at "while ((line = bufferedReader.readLine()) != null)" and don't run. Help me. Thanks all.

Answer

MadProgrammer picture MadProgrammer · Dec 13, 2013

Jsch has some excellent examples in the examples directory, the one in particular you might find of interest is called Exec. You might also be interested in Shell

This is a slightly modified version which skips getting the information from the command line and prompting for the user info and command and simply attempts to connect directly to the remote machine and execute a ls command.

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;
import java.io.InputStream;
import java.util.Properties;

public class TestShell {

    public static void main(String[] arg) {
        try {
            JSch jsch = new JSch();

            Session session = jsch.getSession("username", "computer", 22);

            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);

            // Skip prompting for the password info and go direct...
            session.setPassword("happybunnyslippers");
            session.connect();

            String command = "ls";

            Channel channel = session.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);

            ((ChannelExec) channel).setErrStream(System.err);

            InputStream in = channel.getInputStream();

            System.out.println("Connect to session...");
            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();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

I tested this on my Windows box connecting to one of my Mac boxes without any issues

Updated with hacked Shell example

Basically, this is a hacked example based on the Shell example.

This uses a custom OutputStream to monitor changes to the content being sent from the remote machine and which can issue commands. This is pretty basic, in the fact that all I'm doing is waiting for $ to be send to the output stream and then issuing the next command.

It wouldn't take too much work to modify it so that, based on the current command/command index, you could do different parsing...

import com.jcraft.jsch.*;
import java.awt.*;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import javax.swing.*;

public class TestShell {

    public static void main(String[] arg) {

        try {

            JSch jsch = new JSch();
            String host = null;

            final Session session = jsch.getSession("user", "remotecomputer", 22);
            session.setPassword("fluffybunnyslippers");

            session.setConfig("StrictHostKeyChecking", "no");
            session.connect(30000);   // making a connection with timeout.

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

            PipedInputStream pis = new PipedInputStream();
            final PipedOutputStream pos = new PipedOutputStream(pis);

            channel.setInputStream(pis);
            channel.setOutputStream(new OutputStream() {

                private int cmdIndx = 0;
                private String[] cmds = {
                    "ls\n",
                    "cd ..\n",
                    "ls\n",
                    "exit\n"
                };

                private String line = "";

                @Override
                public void write(int b) throws IOException {
                    char c = (char) b;
                    if (c == '\n') {
                        logout(line);
                        System.out.print(line);
                        line = "";
                    } else {
                        line += c;
                        logout(line);
                        if (line.endsWith("$ ")) {
                            String cmd = cmds[cmdIndx];
                            cmdIndx++;
                            pos.write(cmd.getBytes());
                        }
                    }
                }

                public void logout(String line) {
                    if (line.startsWith("logout")) {
                        System.out.println("...logout...");
                        channel.disconnect();
                        session.disconnect();
                        System.exit(0);
                    }
                }
            });

            channel.connect(3 * 1000);

        } catch (Exception e) {
            System.out.println(e);
        }
    }
}