java調(diào)用遠(yuǎn)程服務(wù)器的shell腳本以及停止的方法實(shí)現(xiàn)
最近接了個(gè)需求,要求遠(yuǎn)程調(diào)shell腳本,你沒聽錯(cuò)?。?!需求就一句話,咱是誰,咱是優(yōu)秀的開發(fā)選手??紤]再三,有兩種實(shí)現(xiàn)方式:
方案一:腳本所在服務(wù)器安裝一個(gè)客戶端,也就是自己寫的一個(gè)小程序,本地通過端口調(diào)目標(biāo)服務(wù)器的程序,然后程序調(diào)本機(jī)上的shell腳本!
優(yōu)點(diǎn):通過端口調(diào)用,用戶不用暴露服務(wù)器的賬號(hào)密碼,安全性高
缺點(diǎn):我們需要一直維護(hù)這個(gè)客戶端程序,而且每接入一臺(tái)服務(wù)器,都得安裝該客戶端,另外非??简?yàn)客戶端程序的健壯性。
方案二:本地直接通過IP,服務(wù)器賬號(hào)密碼調(diào)遠(yuǎn)程服務(wù)器的shell腳本
優(yōu)點(diǎn):代碼易開發(fā),擴(kuò)展時(shí)只用擴(kuò)展服務(wù)端代碼即可
缺點(diǎn):用戶服務(wù)器的賬號(hào)密碼會(huì)暴露給服務(wù)端,密碼安全問題
把每種方案的優(yōu)缺點(diǎn)匯報(bào)給leader,leader說:按第二種來吧
來吧??!開干,廢話不多說,直接上代碼:
導(dǎo)入程序所需的軟件包:
<dependency> <groupId>org.jvnet.hudson</groupId> <artifactId>ganymed-ssh2</artifactId> <version>build210-hudson-1</version> </dependency>
程序涉及的demo:
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import org.apache.commons.io.IOUtils;
import ch.ethz.ssh2.ChannelCondition;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
public class RemoteShellExecutor {
private Connection conn;
/** 遠(yuǎn)程機(jī)器IP */
private String ip;
/** 用戶名 */
private String osUsername;
/** 密碼 */
private String password;
private String charset = Charset.defaultCharset().toString();
private final String GET_SHELL_PID = "ps -ef | grep '%s' | grep -v grep |awk '{print $2}'";
private final String KILL_SHELL_PID = "kill -15 %s";
private static final int TIME_OUT = 1000 * 5 * 60;
/**
* 構(gòu)造函數(shù)
* @param ip
* @param usr
* @param pasword
*/
public RemoteShellExecutor(String ip, String usr, String pasword) {
this.ip = ip;
this.osUsername = usr;
this.password = pasword;
}
/**
* 登錄
* @return
* @throws IOException
*/
private boolean login() throws IOException {
conn = new Connection(ip);
conn.connect();
return conn.authenticateWithPassword(osUsername, password);
}
/**
* 執(zhí)行腳本
*
* @param cmds
* @return
* @throws Exception
*/
public ExecuteResultVO exec(String cmds) throws Exception {
InputStream stdOut = null;
InputStream stdErr = null;
ExecuteResultVO executeResultVO = new ExecuteResultVO();
String outStr = "";
String outErr = "";
int ret = -1;
try {
if (login()) {
// Open a new {@link Session} on this connection
Session session = conn.openSession();
// Execute a command on the remote machine.
session.execCommand(cmds);
stdOut = new StreamGobbler(session.getStdout());
outStr = processStream(stdOut, charset);
stdErr = new StreamGobbler(session.getStderr());
outErr = processStream(stdErr, charset);
session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT);
System.out.println("outStr=" + outStr);
System.out.println("outErr=" + outErr);
ret = session.getExitStatus();
executeResultVO.setOutStr(outStr);
executeResultVO.setOutErr(outErr);
} else {
throw new Exception("登錄遠(yuǎn)程機(jī)器失敗" + ip); // 自定義異常類 實(shí)現(xiàn)略
}
} finally {
if (conn != null) {
conn.close();
}
IOUtils.closeQuietly(stdOut);
IOUtils.closeQuietly(stdErr);
}
return ret;
}
/**
* @param in
* @param charset
* @return
* @throws IOException
* @throws UnsupportedEncodingException
*/
private String processStream(InputStream in, String charset) throws Exception {
byte[] buf = new byte[1024];
StringBuilder sb = new StringBuilder();
int len = 0;
while ((len=in.read(buf)) != -1) {
sb.append(new String(buf,0,len, charset));
}
return sb.toString();
}
public static void main(String args[]) throws Exception {
//調(diào)遠(yuǎn)程shell
RemoteShellExecutor executor = new RemoteShellExecutor("192.168.234.123", "root", "beebank");
System.out.println(executor.exec("sh /data/checkMysql.sh"));
//獲取遠(yuǎn)程shell 進(jìn)程 pid
ExecuteResultVO executeResultVO = executor.exec(String.format(GET_SHELL_PID,"sh /data/checkMysql.sh"));
//殺掉shell進(jìn)程
ExecuteResultVO executeResultVO1 = executor.exec(String.format(KILL_SHELL_PID ,executeResultVO.getOutStr()));
}
public class ExecuteResultVO<T>{
private String outStr;
private String outErr;
//省略get set
}
}
經(jīng)過測試也確實(shí)好用啊,大家可以根據(jù)這個(gè)demo進(jìn)行相應(yīng)的修改。到此這篇關(guān)于java調(diào)遠(yuǎn)程服務(wù)器的shell腳本以及停止的方法實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)java調(diào)遠(yuǎn)程shell腳本內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Struts2學(xué)習(xí)筆記(3)-DMI動(dòng)態(tài)調(diào)用方式
本文主要介紹Struts2的DMI動(dòng)態(tài)調(diào)用的兩種方式,簡單實(shí)用,希望能給大家做一個(gè)參考。2016-06-06
SpringBoot中LogBack日志配置與多環(huán)境實(shí)戰(zhàn)
在現(xiàn)代軟件開發(fā)中,日志記錄是不可或缺的一部分,Spring Boot 提供了多種日志框架的支持,其中 Logback 是一個(gè)非常流行的選擇,因?yàn)樗唵巍⒏咝夜δ軓?qiáng)大,本文將介紹如何在 Spring Boot 項(xiàng)目中配置 Logback,并實(shí)現(xiàn)不同環(huán)境下的日志配置,需要的朋友可以參考下2025-01-01
Java前后端的JSON傳輸方式(前后端JSON格式轉(zhuǎn)換)
這篇文章主要介紹了Java前后端的JSON傳輸方式(前后端JSON格式轉(zhuǎn)換),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
一文深入分析java.lang.ClassNotFoundException異常
這篇文章主要給大家介紹了關(guān)于java.lang.ClassNotFoundException異常的相關(guān)資料,java.lang.ClassNotFoundException是Java編程時(shí)經(jīng)常會(huì)遇到的一個(gè)異常,它表示JVM在嘗試加載某個(gè)類時(shí)未能找到該類,需要的朋友可以參考下2023-10-10
一文學(xué)透ApplicationContext繼承接口功能及與BeanFactory區(qū)別
這篇文章主要為大家介紹了ApplicationContext繼承接口功能及與BeanFactory區(qū)別示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
SpringBoot實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的項(xiàng)目實(shí)踐
在實(shí)際開發(fā)過程中,我們經(jīng)常遇到需要同時(shí)操作多個(gè)數(shù)據(jù)源的情況,本文主要介紹了SpringBoot實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04
Java報(bào)錯(cuò):java.lang.UnsatisfiedLinkError問題的解決辦法
在Java開發(fā)中,java.lang.UnsatisfiedLinkError是一種與本地方法調(diào)用相關(guān)的常見異常,本文將詳細(xì)分析這一異常的背景、可能的原因、錯(cuò)誤代碼示例、正確代碼示例,以及編寫代碼時(shí)需要注意的事項(xiàng),需要的朋友可以參考下2024-09-09
Spring Security Remember me使用及原理詳解
這篇文章主要介紹了Spring Security Remember me使用及原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09

