0

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.

Quochg
  • 11
  • 1
  • 2

1 Answers1

3

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);
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • It execute multiplex command??? I using j2ssh library but it error when i get inputreader and read it. the jsch can do it??? Thanks – Quochg Dec 13 '13 at 07:42
  • yep. i want put 2 or more 2 command. currently i want to send first command is "cd /export/home/ops/bin" after is "./viewlinkload –time 20131205-19". The second command is identifier of command first. The command first is dir. Help me Thanks – Quochg Dec 13 '13 at 08:06
  • Take a look at the `Shell` example in the `examples` directory. This basically allows you to start a "shell" and execute commands as you like – MadProgrammer Dec 13 '13 at 08:07
  • means send command is limited??? this is the first is work with it. please help me detail. =========== i have two command need run. the command is run before. String command = "cd /export/home/ops/bin"; String command1 = "./viewlinkload –time 20131205-19"; Channel channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); ((ChannelExec) channel).setCommand(command1); ((ChannelExec) channel).setErrStream(System.err); InputStream in = channel.getInputStream(); =========== Thanks u – Quochg Dec 13 '13 at 08:13
  • Hi MadProgrammer. I copy and run but it don't return. Require of me is simple. -- 1.Connect to server by ssh 2. Send command "cd /export/home/ops/bin" open dir in server 3. Send ./viewlinkload –time 20131205-19 execute command and return result 4. Read output from server and save in table or file. --- i has connect Server ok but I don't know send multiple command opend dir and send command get result from server after process output dât save to file,v.v. this is the first i work with ssh by java code. Help me. thanks u – Quochg Dec 13 '13 at 09:30
  • Did not return what? Basically it's looking for `logout` to be returned from the remote computer, perhaps your remote is sending back something else. Start by running the `Shell` example included with `jsch` and see what the results are – MadProgrammer Dec 13 '13 at 09:34
  • it only reuturn message "Last login: Fri Dec 13 16:07:19 2013 from 10.30.3.134". Berfor i run the fisrt script with one command it work and get filename from server. Now I want send 2 command to server but it don't work. – Quochg Dec 13 '13 at 09:38
  • Okay. They way I have it setup, as I said, I'm waiting for a prompt (end in `$ `). What is the command prompt you are seeing.. – MadProgrammer Dec 13 '13 at 09:51
  • in server when i conneced is show "SVK_NGN_sam_1_1_1 SAM001:>" and when the end command and down the line character show is "SVK_NGN_sam_1_1_1 SAM001:>". Example SVK_NGN_sam_1_1_1 SAM001:>ls click Enter. ">" this is prompt u want know??? – Quochg Dec 13 '13 at 09:58
  • Yep, change the `if (line.endsWith("$ ")) {` to something more like `if (line.endsWith(":>")) {` or `if (line.endsWith(":> ")) {` if that doesn't work... – MadProgrammer Dec 13 '13 at 10:00
  • Hi MadProgrammer When i change prompt is ":>" it running but have issue. i put command is: private String[] cmds = { "cd /export/home/ops/bin\n", "ls\n", "exit\n" }; ----------------------------------------- Last login: Fri Dec 13 17:05:48 2013 from 10.30.3.134 ]0;root@SVK_NGN_sam_1_1_1:~SVK_NGN_sam_1_1_1 SAM001:> cd /export/home/ops/bin ]0;root@SVK_NGN_sam_1_1_1:/export/home/ops/binSVK_NGN_sam_1_1_1 I see have a lot of character "root@SVK_NGN_sam_1_1_1:~". I want show format root@SVK_NGN_sam_1_1_1: cd /command root@SVK_NGN_sam_1_1_1: ./comand. Can U config it?? Thanks u. – Quochg Dec 13 '13 at 10:32
  • it show a lot of value root@SVK_NGN_sam_1_1_1. examle: ;root@SVK_NGN_sam_1_1_1:~SVK_NGN_sam_1_1_1 SAM001:> cd /export/home/ops/bin ]0;root@SVK_NGN_sam_1_1_1:/export/home/ops/binSVK_NGN_sam_1_1_1 I see have a lot of character "root@SVK_NGN_sam_1_1_1:~". -------> I want each command show one "root@SVK_NGN_sam_1_1_1". Can u config it?? – Quochg Dec 13 '13 at 10:58
  • hi MadProgrammer. Now i want write all infomation command and result get to server in file .txt. can U help me??? Thanks u. – Quochg Dec 14 '13 at 10:31