39

I am new to this kind of Java application and looking for some sample code on how to connect to a remote server using SSH , execute commands, and get output back using Java as programming language.

2

6 Answers 6

24

Have a look at Runtime.exec() Javadoc

Process p = Runtime.getRuntime().exec("ssh myhost");
PrintStream out = new PrintStream(p.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));

out.println("ls -l /home/me");
while (in.ready()) {
  String s = in.readLine();
  System.out.println(s);
}
out.println("exit");

p.waitFor();
Sign up to request clarification or add additional context in comments.

9 Comments

@Zubair - The guy who gave -1 hasn't bothered to explain his point of view. This solution does work because it is as simple as only possible. It's not "pure java" though, this is a drawback, but if you're on Linux, you can't make it simpler without using third party libraries.
And how would you handle passwords on this?
@mors - #1 keys authentication, #2 - same as any other input/output of the child process
This does not work, at least you could have tested your code and found out that there is no Runtime.exec but a Runtime.getInstance.exec. Even with this correction, the output of ls is not shown.
@David - try with Runtime.getRuntime().exec() on Linux from command line
|
13

JSch is a pure Java implementation of SSH2 that helps you run commands on remote machines. You can find it here, and there are some examples here.

You can use exec.java.

Comments

9

I created solution based on JSch library:

import com.google.common.io.CharStreams
import com.jcraft.jsch.ChannelExec
import com.jcraft.jsch.JSch
import com.jcraft.jsch.JSchException
import com.jcraft.jsch.Session

import static java.util.Arrays.asList

class RunCommandViaSsh {

    private static final String SSH_HOST = "test.domain.com"
    private static final String SSH_LOGIN = "username"
    private static final String SSH_PASSWORD = "password"

    public static void main() {
        System.out.println(runCommand("pwd"))
        System.out.println(runCommand("ls -la"));
    }

    private static List<String> runCommand(String command) {
        Session session = setupSshSession();
        session.connect();

        ChannelExec channel = (ChannelExec) session.openChannel("exec");
        try {
            channel.setCommand(command);
            channel.setInputStream(null);
            InputStream output = channel.getInputStream();
            channel.connect();

            String result = CharStreams.toString(new InputStreamReader(output));
            return asList(result.split("\n"));

        } catch (JSchException | IOException e) {
            closeConnection(channel, session)
            throw new RuntimeException(e)

        } finally {
            closeConnection(channel, session)
        }
    }

    private static Session setupSshSession() {
        Session session = new JSch().getSession(SSH_LOGIN, SSH_HOST, 22);
        session.setPassword(SSH_PASSWORD);
        session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
        session.setConfig("StrictHostKeyChecking", "no"); // disable check for RSA key
        return session;
    }

    private static void closeConnection(ChannelExec channel, Session session) {
        try {
            channel.disconnect()
        } catch (Exception ignored) {
        }
        session.disconnect()
    }
}

3 Comments

should have added jsch .jar file or respective maven dependency.
Your answer was very useful but there are some mistakes in code. As far as topic is close it is impossible to enclose edited class here for newcomers so just take a look at it on github github.com/menkom/JavaSshClient/blob/main/SshClient.java . Almost the same is on official page showing way of usage jcraft.com/jsch/examples/Exec.java.html but my class is ready to use without knowledge of realization.
can we run tail -f command and keep printing the log
7

Below is the easiest way to SSh in java. Download any of the file in the below link and extract, then add the jar file from the extracted file and add to your build path of the project http://www.ganymed.ethz.ch/ssh2/ and use the below method

public void SSHClient(String serverIp,String command, String usernameString,String password) throws IOException{
        System.out.println("inside the ssh function");
        try
        {
            Connection conn = new Connection(serverIp);
            conn.connect();
            boolean isAuthenticated = conn.authenticateWithPassword(usernameString, password);
            if (isAuthenticated == false)
                throw new IOException("Authentication failed.");        
            ch.ethz.ssh2.Session sess = conn.openSession();
            sess.execCommand(command);  
            InputStream stdout = new StreamGobbler(sess.getStdout());
            BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
            System.out.println("the output of the command is");
            while (true)
            {
                String line = br.readLine();
                if (line == null)
                    break;
                System.out.println(line);
            }
            System.out.println("ExitCode: " + sess.getExitStatus());
            sess.close();
            conn.close();
        }
        catch (IOException e)
        {
            e.printStackTrace(System.err);

        }
    }

1 Comment

can this be done in spring boot ?
3

You may take a look at this Java based framework for remote command execution, incl. via SSH: https://github.com/jkovacic/remote-exec It relies on two opensource SSH libraries, either JSch (for this implementation even an ECDSA authentication is supported) or Ganymed (one of these two libraries will be enough). At the first glance it might look a bit complex, you'll have to prepare plenty of SSH related classes (providing server and your user details, specifying encryption details, provide OpenSSH compatible private keys, etc., but the SSH itself is quite complex too). On the other hand, the modular design allows for simple inclusion of more SSH libraries, easy implementation of other command's output processing or even interactive classes etc.

Comments

1

I used ganymede for this a few yeas ago... http://www.cleondris.ch/opensource/ssh2/

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.