Java如何通過(guò)ssh遠(yuǎn)程連接主機(jī)并執(zhí)行命令
Java通過(guò)ssh遠(yuǎn)程連接主機(jī)并執(zhí)行命令
需要用到的jar包:

主體代碼:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
public class SshLinux {
private static final Logger log = LoggerFactory.getLogger(SshLinux.class);
private static String DEFAULTCHART="UTF-8";
/**
* 登錄主機(jī)
* @return
* 登錄成功返回true,否則返回false
*/
public static Connection login(String ip,
String userName,
String userPwd){
boolean flg=false;
Connection conn = null;
try {
conn = new Connection(ip);
conn.connect();//連接
flg=conn.authenticateWithPassword(userName, userPwd);//認(rèn)證
if(flg){
log.info("=========登錄成功========="+conn);
return conn;
}
} catch (IOException e) {
log.error("=========登錄失敗========="+e.getMessage());
e.printStackTrace();
}
return conn;
}
/**
* 遠(yuǎn)程執(zhí)行shll腳本或者命令
* @param cmd
* 即將執(zhí)行的命令
* @return
* 命令執(zhí)行完后返回的結(jié)果值
*/
public static String execute(Connection conn,String cmd){
String result="";
try {
if(conn !=null){
Session session= conn.openSession();//打開(kāi)一個(gè)會(huì)話(huà)
session.execCommand(cmd);//執(zhí)行命令
result=processStdout(session.getStdout(),DEFAULTCHART);
//如果為得到標(biāo)準(zhǔn)輸出為空,說(shuō)明腳本執(zhí)行出錯(cuò)了
if(StringUtils.isBlank(result)){
log.info("得到標(biāo)準(zhǔn)輸出為空,鏈接conn:"+conn+",執(zhí)行的命令:"+cmd);
result=processStdout(session.getStderr(),DEFAULTCHART);
}else{
log.info("執(zhí)行命令成功,鏈接conn:"+conn+",執(zhí)行的命令:"+cmd);
}
conn.close();
session.close();
}
} catch (IOException e) {
log.info("執(zhí)行命令失敗,鏈接conn:"+conn+",執(zhí)行的命令:"+cmd+" "+e.getMessage());
e.printStackTrace();
}
return result;
}
/**
* 解析腳本執(zhí)行返回的結(jié)果集
* @param in 輸入流對(duì)象
* @param charset 編碼
* @return
* 以純文本的格式返回
*/
private static String processStdout(InputStream in, String charset){
InputStream stdout = new StreamGobbler(in);
StringBuffer buffer = new StringBuffer();;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(stdout,charset));
String line=null;
while((line=br.readLine()) != null){
buffer.append(line+"\n");
}
} catch (UnsupportedEncodingException e) {
log.error("解析腳本出錯(cuò):"+e.getMessage());
e.printStackTrace();
} catch (IOException e) {
log.error("解析腳本出錯(cuò):"+e.getMessage());
e.printStackTrace();
}
return buffer.toString();
}
}注意:ganymed這個(gè)jar包,每次只能執(zhí)行一條命令,如果一條命令執(zhí)行了沒(méi)有關(guān)閉,再去執(zhí)行第二條則會(huì)throw new IOException("A remote execution has already started.");
若希望同時(shí)執(zhí)行多條命令,可以在傳入的cmd字符串中用&&連接多條命令。
如:

那么多條命令執(zhí)行的所有結(jié)果將會(huì)一同作為返回的字符串。

ssh 遠(yuǎn)程腳本執(zhí)行 java: command not found
ssh 遠(yuǎn)程主機(jī)腳本執(zhí)行、執(zhí)行 java -version,報(bào)如題錯(cuò)誤
[root@doris-fe-01 module]# ./install.sh "java -version "
java -version
doris-fe-01 ...
bash: java: command not found
doris-fe-02 ...
bash: java: command not found### 直接登錄遠(yuǎn)程主機(jī),java -version 正常執(zhí)行
[root@doris-fe-01 module]# ssh doris-fe-02
Last login: Mon Nov 14 16:54:51 2022
[root@doris-fe-02 ~]# java -version
java version "1.8.0_141"
Java(TM) SE Runtime Environment (build 1.8.0_141-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.141-b15, mixed mode)
處理
export JAVA_HOME=/opt/module/jdk1.8.0_141' >>/etc/bashrc echo 'export PATH=/opt/module/jdk1.8.0_141/bin:$PATH' >>/etc/bashrc ###? source /etc/bashrc
[root@doris-fe-01 module]# ./install.sh "java -version "
java -version
doris-fe-01 ...
java version "1.8.0_141"
Java(TM) SE Runtime Environment (build 1.8.0_141-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.141-b15, mixed mode)
...
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解使用spring boot admin監(jiān)控spring cloud應(yīng)用程序
本篇文章主要介紹了詳解使用spring boot admin監(jiān)控spring cloud應(yīng)用程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
深入理解Java虛擬機(jī) JVM 內(nèi)存結(jié)構(gòu)
本節(jié)將會(huì)介紹一下JVM的內(nèi)存結(jié)構(gòu),JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的各個(gè)組成部分:堆,方法區(qū),程序計(jì)數(shù)器,Java虛擬機(jī)棧,本地方法棧,還會(huì)對(duì)Java堆的分代劃分做個(gè)簡(jiǎn)單的介紹2021-09-09
Spring?MVC?請(qǐng)求映射路徑的配置實(shí)現(xiàn)前后端交互
在Spring?MVC中,請(qǐng)求映射路徑是指與特定的請(qǐng)求處理方法關(guān)聯(lián)的URL路徑,這篇文章主要介紹了Spring?MVC?請(qǐng)求映射路徑的配置,實(shí)現(xiàn)前后端交互,需要的朋友可以參考下2023-09-09
如何使用SpringBoot集成Kafka實(shí)現(xiàn)用戶(hù)數(shù)據(jù)變更后發(fā)送消息
Spring Boot集成Kafka實(shí)現(xiàn)用戶(hù)數(shù)據(jù)變更后,向其他廠商發(fā)送消息,我們需要考慮配置Kafka連接、創(chuàng)建Kafka Producer發(fā)送消息、監(jiān)聽(tīng)用戶(hù)數(shù)據(jù)變更事件,并將事件轉(zhuǎn)發(fā)到Kafka,本文分步驟給大家講解使用SpringBoot集成Kafka實(shí)現(xiàn)用戶(hù)數(shù)據(jù)變更后發(fā)送消息,感興趣的朋友一起看看吧2024-07-07
Springboot自帶定時(shí)任務(wù)實(shí)現(xiàn)動(dòng)態(tài)配置Cron參數(shù)方式
這篇文章主要介紹了Springboot自帶定時(shí)任務(wù)實(shí)現(xiàn)動(dòng)態(tài)配置Cron參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Spring IOC創(chuàng)建對(duì)象的兩種方式
這篇文章主要給大家介紹了關(guān)于Spring IOC創(chuàng)建對(duì)象的兩種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Mybatis的mapper文件中#和$的區(qū)別示例解析
MyBatis的mapper文件中,#{}和${}是兩種參數(shù)占位符,核心差異在于參數(shù)解析方式、SQL 注入風(fēng)險(xiǎn)、適用場(chǎng)景,以下從底層原理、使用場(chǎng)景、示例等維度詳細(xì)解析,本文介紹Mybatis的mapper文件中#和$的區(qū)別,感興趣的朋友跟隨小編一起看看吧2025-12-12
JavaWeb項(xiàng)目實(shí)現(xiàn)文件上傳動(dòng)態(tài)顯示進(jìn)度實(shí)例
本篇文章主要介紹了JavaWeb項(xiàng)目實(shí)現(xiàn)文件上傳動(dòng)態(tài)顯示進(jìn)度實(shí)例,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-04-04

