在 Java 中可以通過 SSH2 協議遠程執行 Linux 系統的命令或 Shell 腳本。
主要依賴包:ganymed-ssh2-build262.jar
1、添加依賴
<!-- https://mvnrepository.com/artifact/ch.ethz.ganymed/ganymed-ssh2 -->
<dependency>
<groupId>ch.ethz.ganymed</groupId>
<artifactId>ganymed-ssh2</artifactId>
<version>262</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
2、Api說明
-
首先構造一個連接器,傳入一個需要登陸的ip地址;
Connection conn = new Connection(hostname);
-
模擬登陸目的服務器,傳入用戶名和密碼;
boolean isAuthenticated = conn.authenticateWithPassword(username, password);它會返回一個布爾值,true 代表成功登陸目的服務器,否則登陸失敗。
-
打開一個session,執行你需要的linux 腳本命令;
Session session = conn.openSession();
session.execCommand(“ifconfig”); -
接收目標服務器上的控制檯返回結果,讀取br中的內容;
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout)); -
得到腳本運行成功與否的標誌 :0-成功 非0-失敗
System.out.println(“ExitCode: ” + sess.getExitStatus());
-
關閉session和connection
sess.close();
conn.close();
備註:
1、通過第2步認證成功後,當前目錄就位於/home/username/目錄之下,你可以指定腳本文件所在的絕對路徑,或者通過cd導航到腳本文件所在的目錄,然後傳遞執行腳本所需要的參數,完成腳本調用執行。
2、執行腳本以後,可以獲取腳本執行的結果文本,需要對這些文本進行正確編碼後返回給客戶端,避免亂碼產生。
3、如果你需要執行多個linux控制檯腳本,比如第一個腳本的返回結果是第二個腳本的入參,你必須打開多個Session,也就是多次調用
Session sess = conn.openSession();
使用完畢記得關閉就可以了。
3、實例代碼
package xxx.xxx.xxxx.xxx;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import com.gisquest.platform.test;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.util.IOUtils;
import java.io.*;
/**
* @Author wangy
* @Date 2019/10/10 10:00
* @Version 1.1
* * 遠程執行linux的shell script
*/
public class RemoteExecuteCommand {
// 字符編碼默認是utf-8
private static String DEFAULTCHART = "UTF-8";
private Connection conn;
private String ip;
private String userName;
private String userPwd;
public RemoteExecuteCommand(String ip, String userName, String userPwd) {
this.ip = ip;
this.userName = userName;
this.userPwd = userPwd;
}
public RemoteExecuteCommand() {
}
/**
* 遠程登錄linux主機
* @since V0.1
* @return 登錄成功返回true,否則返回false
* @throws Exception
*/
public Boolean login() throws Exception {
boolean flg = false;
try {
conn = new Connection(ip);
// 連接
conn.connect();
// 認證
flg = conn.authenticateWithPassword(userName, userPwd);
} catch (IOException e) {
throw new Exception("遠程連接服務器失敗", e);
}
return flg;
}
/**
* 遠程執行shll腳本或者命令
* @param cmd 即將執行的命令
* @return 命令執行完後返回的結果值
* @throws Exception
* @since V0.1
*/
public String execute(String cmd) throws Exception {
String result = "";
Session session = null;
try {
if (login()) {
// 打開一個會話
session = conn.openSession();
// 執行命令
session.execCommand(cmd);
result = processStdout(session.getStdout(), DEFAULTCHART);
// 如果爲輸出爲空,說明腳本執行出錯了
if (StringUtils.isBlank(result)) {
result = processStdout(session.getStderr(), DEFAULTCHART);
}
conn.close();
session.close();
}
} catch (IOException e) {
throw new Exception("命令執行失敗", e);
} finally {
if (conn != null) {
conn.close();
}
if (session != null) {
session.close();
}
}
return result;
}
/**
* 解析腳本執行返回的結果集
*
* @param in 輸入流對象
* @param charset 編碼
* @since V0.1
* @return 以純文本的格式返回
* @throws Exception
*/
private String processStdout(InputStream in, String charset) throws Exception {
InputStream stdout = new StreamGobbler(in);
StringBuffer buffer = new StringBuffer();
InputStreamReader isr = null;
BufferedReader br = null;
try {
isr = new InputStreamReader(stdout, charset);
br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
buffer.append(line + "\n");
}
} catch (UnsupportedEncodingException e) {
throw new Exception("不支持的編碼字符集異常", e);
} catch (IOException e) {
throw new Exception("讀取指紋失敗", e);
} finally {
IOUtils.close(br);
IOUtils.close(isr);
IOUtils.close(stdout);
}
return buffer.toString();
}
}
4、測試
public static void main(String[] args) throws Exception {
String linuxIP = "192.168.11.107";
String usrName = "root";
String passwd = "*******";
test rec = new test(linuxIP, usrName, passwd);
// 執行命令
System.out.println(rec.execute("ifconfig"));
// 執行腳本
//rec.execute("sh /usr/local/hostmgr/check.sh");
}
控制檯返回結果
參考文章:java遠程調用linux的命令或者腳本