2

How do I run multiple commands in SSH using Java runtime?

the command: ssh [email protected] 'export MYVAR=this/dir/is/cool; /run/my/script /myscript; echo $MYVAR'

@Test
  public void testSSHcmd() throws Exception
  {
    StringBuilder cmd = new StringBuilder();

    cmd.append("ssh ");
    cmd.append("[email protected] ");
    cmd.append("'export ");
    cmd.append("MYVAR=this/dir/is/cool; ");
    cmd.append("/run/my/script/myScript; ");
    cmd.append("echo $MYVAR'");

    Process p = Runtime.getRuntime().exec(cmd.toString());
  }

The command by its self will work but when trying to execute from java run-time it does not. Any suggestions or advice?

2
  • What doesn't work? What happens? Commented Sep 30, 2011 at 14:10
  • I love stackoverflow. Thanks everyone! Commented Sep 30, 2011 at 14:14

6 Answers 6

5

Use the newer ProcessBuilder class instead of Runtime.exec. You can construct one by specifying the program and its list of arguments as shown in my code below. You don't need to use single-quotes around the command. You should also read the stdout and stderr streams and waitFor for the process to finish.

ProcessBuilder pb = new ProcessBuilder("ssh", 
                                       "[email protected]", 
                                       "export MYVAR=this/dir/is/cool; /run/my/script/myScript; echo $MYVAR");
pb.redirectErrorStream(); //redirect stderr to stdout
Process process = pb.start();
InputStream inputStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while((line = reader.readLine())!= null) {
    System.out.println(line);
}
process.waitFor();
Sign up to request clarification or add additional context in comments.

1 Comment

Hi dogbane I need to run multiple ssh commands in a single run, the link which you shared was not clear to me. So ple if you have any clear document can you please share to me. Thanks
1

If the Process just hangs I suspect that /run/my/script/myScript outputs something to stderr. You need to handle that output aswell as stdout:

public static void main(String[] args) throws Exception {
    String[] cmd = {"ssh", "root@localhost", "'ls asd; ls'" };
    final Process p = Runtime.getRuntime().exec(cmd);

    // ignore all errors (print to std err)
    new Thread() {
        @Override
        public void run() {
            try {
                BufferedReader err = new BufferedReader(
                        new InputStreamReader(p.getErrorStream()));
                String in;
                while((in = err.readLine()) != null)
                    System.err.println(in);
                err.close();
            } catch (IOException e) {}
        }
    }.start();

    // handle std out
    InputStreamReader isr = new InputStreamReader(p.getInputStream());
    BufferedReader reader = new BufferedReader(isr);

    StringBuilder ret = new StringBuilder();
    char[] data = new char[1024];
    int read;
    while ((read = reader.read(data)) != -1)
        ret.append(data, 0, read);
    reader.close();

    // wait for the exit code
    int exitCode = p.waitFor();
}

Comments

1

The veriant of Runtime.exec you are calling splits the command string into several tokens which are then passed to ssh. What you need is one of the variants where you can provide a string array. Put the complete remote part into one argument while stripping the outer quotes. Example

Runtime.exec(new String[]{ 
    "ssh", 
    "[email protected]", 
    "export MYVAR=this/dir/is/cool; /run/my/script/myScript; echo $MYVAR"
});

That's it.

Comments

0

You might want to take a look at the JSch library. It allows you to do all sorts of SSH things with remote hosts including executing commands and scripts.

They have examples listed here: http://www.jcraft.com/jsch/examples/

Comments

0

Here is the right way to do it:

Runtime rt=Runtime.getRuntime();
rt.exec("cmd.exe /c start <full path>");

For example:

Runtime rt=Runtime.getRuntime();
rt.exec("cmd.exe /c start C:/aa.txt");

Comments

0

If you are using SSHJ from https://github.com/shikhar/sshj/

public static void main(String[] args) throws IOException {
    final SSHClient ssh = new SSHClient();
    ssh.loadKnownHosts();

    ssh.connect("10.x.x.x");
    try {
        //ssh.authPublickey(System.getProperty("root"));
        ssh.authPassword("user", "xxxx");
        final Session session = ssh.startSession();

        try {
            final Command cmd = session.exec("cd /backup; ls; ./backup.sh");
            System.out.println(IOUtils.readFully(cmd.getInputStream()).toString());
            cmd.join(5, TimeUnit.SECONDS);
            System.out.println("\n** exit status: " + cmd.getExitStatus());
        } finally {
            session.close();
        }
    } finally {
        ssh.disconnect();
    }
}

4 Comments

Hi Depicus I need to run multiple ssh commands in a single run, the link which you shared was not clear to me. So ple if you have any clear document can you please share to me. Thanks
Hi Anand, basically separate each command with a ; and you should be good to go. The link works for me.
okay Depicus. I need to run multiple ssh commands with select query to view the status. I can't execute the query if you know how to execute select query please let me know. Here I Show the full commands. cd /aep/cu/scripts/;./dbutil.ksh E1QA;select * from tgpoa01.aud_trail_dtl where AUD_TRAIL_REC_ID = '-9223372036798689753'
The System.out.println(IOUtils.readFully(cmd.getInputStream()).toString()); line should return any output

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.