Remote execute command in Java example

English 简体中文 繁体中文 ภาษาไทย Tiếng Việt
Summary

When needing to programmatically execute commands on remote systems from a Java application, the JSch library provides a pure Java implementation of SSH2 for this purpose. Developers can establish secure SSH connections, open an "exec" channel, and send commands to a remote server without direct login. The output from these commands is then captured by reading the channel's input stream, enabling automated task execution and centralized result collection, especially useful in distributed environments. The process involves creating a JSch session, configuring connection properties, setting credentials, and managing channel and session lifecycles. Beyond command execution, JSch also supports features like port forwarding and file transfer.

บ่อยครั้งมีความจำเป็นต้องเข้าสู่ระบบระบบระยะไกลและเรียกใช้คำสั่งหรือโปรแกรมบางอย่างเพื่อรับผลลัพธ์ ซอฟต์แวร์หลายตัวสามารถทำหน้าที่นี้ได้ เช่น putty และ gitshell ซอฟต์แวร์เหล่านี้มักจะให้การเข้าถึงระบบระยะไกลอย่างปลอดภัย แต่คุณเคยสงสัยหรือไม่ว่าจะทำอย่างไรหากคุณต้องการเรียกใช้คำสั่งบนระบบต่างๆ หลายระบบพร้อมกันและรับผลลัพธ์เหล่านั้นกลับมาในที่เดียว โดยเฉพาะอย่างยิ่งในยุคบิ๊กดาต้า งานหลายอย่างอาจทำงานบนระบบกระจายต่างๆ และคุณต้องการที่จะมีที่เดียวในการสะสมผลลัพธ์

ในโพสต์นี้ เราจะแนะนำไลบรารี Java ที่สามารถช่วยให้บรรลุเป้าหมายนี้ได้ -- JSch มันเป็นการใช้งาน SSH2 แบบ Java แท้ๆ JSch ช่วยให้คุณสามารถเชื่อมต่อกับเซิร์ฟเวอร์ sshd และใช้การส่งต่อพอร์ต การส่งต่อ X11 การถ่ายโอนไฟล์ ฯลฯ และคุณสามารถรวมฟังก์ชันการทำงานลงในโปรแกรม Java ของคุณเองได้

ประโยชน์ของการใช้งานคือ คุณสามารถเชื่อมต่อกับเซิร์ฟเวอร์ระยะไกลและเรียกใช้คำสั่งบางอย่างได้โดยไม่ต้องเข้าสู่ระบบจริง ด้านล่างนี้เป็นตัวอย่างของวิธีที่คุณสามารถเรียกใช้ ls -la บนเซิร์ฟเวอร์ Linux ระยะไกล

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();
		}
	}
}

หลังจากเรียกใช้โปรแกรม ผลลัพธ์คือ :

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

มันค่อนข้างสะดวก หากคุณต้องการเรียกใช้คำสั่งเดียวกันบนสองระบบระยะไกล คุณเพียงแค่สร้างเซสชันและช่องใหม่และทำเช่นเดียวกัน

JSch สามารถช่วยทำอะไรได้อีกมากมาย รวมถึงการส่งต่อพอร์ต การถ่ายโอนไฟล์ ฯลฯ

JSCH EXAMPLE DISTRIBUTED SYSTEM SSH2

  RELATED

  COMMENTS

11
Anonymous
Aug 6, 2017 at 11:10 pm

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
Aug 7, 2017 at 9:03 am

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
May 14, 2018 at 4:30 am

Hi Sonic,

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

Thanks,

Sara

Ke Pi
May 14, 2018 at 10:00 am

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
Aug 14, 2018 at 9:04 am

How can we execute multiple commands ?

Ke Pi
Aug 14, 2018 at 10:58 am

Can try to delimit the command with semicolon

Anonymous
Dec 9, 2019 at 4:01 am

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

Ke Pi
Dec 10, 2019 at 9:08 am

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

Anonymous
Dec 10, 2019 at 10:05 am

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

Ke Pi
Dec 11, 2019 at 8:14 am

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

Prasun
Jun 7, 2020 at 2:56 am

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.