Remote execute command in Java example

  sonic0002        2014-12-12 03:20:19       46,344        11    

Frequently there is a need to logon to a remote system and run some commands or programs to get the output, many software can serve this purpose such as putty and gitshell.These software usually provide secure access to the remote system. But have you ever wondered what to do if you need to run commands on many different systems at the same time and get all these results back at a single place? Especially in big data era, many tasks may run on different distributed systems and you want o have a single place to accumulate the result.

In this post, we will introduce a Java library which can help achieve this -- JSch. It is a pure Java implementation of SSH2. JSch allows you to connect to an sshd server and use port forwarding, X11 forwarding, file transfer, etc., and you can integrate its functionality into your own Java programs. 

The benefit of using it is that you can programmablly connect to the remove server and execute some commands there without actually login to it. Below is an example on how you can run ls -la on a remote Linux server.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;

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


public class JSchTest {
	public static void main(String[] args){
		try{
			String command = "ls -la";
			String host = "host_ip";
			String user = "username";
			String password = "password";
			
			JSch jsch = new JSch();
			Session session = jsch.getSession(user, host, 22);
			Properties config = new Properties();
			config.put("StrictHostKeyChecking", "no");
			session.setConfig(config);;
			session.setPassword(password);
			session.connect();
			
			Channel channel = session.openChannel("exec");
			((ChannelExec)channel).setCommand(command);
			channel.setInputStream(null);
			((ChannelExec)channel).setErrStream(System.err);
			
			InputStream input = channel.getInputStream();
			channel.connect();
			
			System.out.println("Channel Connected to machine " + host + " server with command: " + command ); 
			
			try{
				InputStreamReader inputReader = new InputStreamReader(input);
				BufferedReader bufferedReader = new BufferedReader(inputReader);
				String line = null;
				
				while((line = bufferedReader.readLine()) != null){
					System.out.println(line);
				}
				bufferedReader.close();
				inputReader.close();
			}catch(IOException ex){
				ex.printStackTrace();
			}
			
			channel.disconnect();
			session.disconnect();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
}

After running the program, the output is :

Channel Connected to machine hostname server with command: ls -la
total 1367872
drwxr-xr-x 33 peter users      4096 Dec 11 16:49 .
drwxr-xr-x  6 root  root       4096 Mar 21  2014 ..
-rw-------  1 peter users     15607 Dec 11 19:01 .bash_history
-rw-r--r--  1 peter users      1177 Mar 21  2014 .bashrc
drwxr-xr-x  2 peter users      4096 Sep 12 09:47 bin
drwxrwxrwx  2 peter users      4096 Sep  3 14:10 cfg

It's pretty convenient. If you want to run the same command on two remote systems, you just need to create a new session and channel and do the same.

JSch can help do a lot more including port forwarding, file transfer etc.

JSCH  EXAMPLE  DISTRIBUTED SYSTEM  SSH2 

       

  RELATED


  11 COMMENTS


Anonymous [Reply]@ 2017-08-06 23:10:19

Hey Sonic,

Great article. That is what i was looking for. Thanks

But i am getting a "com.jcraft.jsch.JSchException: java.net.ConnectException: Connection refused: connect" error.

Any insights here?

Ke Pi [Reply]@ 2017-08-07 09:03:53

Apparently the error you are seeing is that remote end refuses the connection. Maybe the port is not accessible. Please make sure that you can telnet to the remote host at port 22.

Anonymous [Reply]@ 2018-05-14 04:30:51

Hi Sonic,

on a Windows server how can I connect? I can't use 22 port.

Thanks,

Sara

Ke Pi [Reply]@ 2018-05-14 10:00:39

What do you mean by you cannot use port 22? The port you should use depends on what port the SSHd service is listening at the other end. 

Venni [Reply]@ 2018-08-14 09:04:21

How can we execute multiple commands ?

Ke Pi [Reply]@ 2018-08-14 10:58:26

Can try to delimit the command with semicolon

Anonymous [Reply]@ 2019-12-09 04:01:37

After sending a command I get a prompt where I need to provide an user input. How can I do this?

Ke Pi [Reply]@ 2019-12-10 09:08:27

Ideally it should not prompt as you already put username. Out of curiosity, what prompt do you see? In your Java output?

Anonymous [Reply]@ 2019-12-10 10:05:50

It’s like an incident number where i need to give user input

Ke Pi [Reply]@ 2019-12-11 08:14:21

Maybe it's related to interactive mode of ssh? https://unix.stackexchange.com/questions/349425/ssh-command-and-non-interactive-non-login-shell

Prasun [Reply]@ 2020-06-07 02:56:40

i'm new to java.. just trying to creating ssh connection and execute the shell script which has pretty long output in console. How can we have handle such scenario. I see script code is getting hanged and not display the console output.



  RANDOM FUN

Brick on programmer desk

After putting a brick on the desk, no product manager has insane requirement anymore and no trash talk neither.