這篇文章給大家分享的是有關java如何調用遠程服務器的shell腳本的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
最近接了個需求,要求遠程調shell腳本,你沒聽錯?。?!需求就一句話,咱是誰,咱是優秀的開發選手??紤]再三,有兩種實現方式:
方案一:腳本所在服務器安裝一個客戶端,也就是自己寫的一個小程序,本地通過端口調目標服務器的程序,然后程序調本機上的shell腳本!
優點:通過端口調用,用戶不用暴露服務器的賬號密碼,安全性高
缺點:我們需要一直維護這個客戶端程序,而且每接入一臺服務器,都得安裝該客戶端,另外非??简灴蛻舳顺绦虻慕研?。
方案二:本地直接通過IP,服務器賬號密碼調遠程服務器的shell腳本
優點:代碼易開發,擴展時只用擴展服務端代碼即可
缺點:用戶服務器的賬號密碼會暴露給服務端,密碼安全問題
把每種方案的優缺點匯報給leader,leader說:按第二種來吧
來吧??!開干,廢話不多說,直接上代碼:
導入程序所需的軟件包:
<dependency> <groupId>org.jvnet.hudson</groupId> <artifactId>ganymed-ssh3</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.ssh3.ChannelCondition;
import ch.ethz.ssh3.Connection;
import ch.ethz.ssh3.Session;
import ch.ethz.ssh3.StreamGobbler;
public class RemoteShellExecutor {
private Connection conn;
/** 遠程機器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;
/**
* 構造函數
* @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);
}
/**
* 執行腳本
*
* @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("登錄遠程機器失敗" + ip); // 自定義異常類 實現略
}
} 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 {
//調遠程shell
RemoteShellExecutor executor = new RemoteShellExecutor("192.168.234.123", "root", "beebank");
System.out.println(executor.exec("sh /data/checkMysql.sh"));
//獲取遠程shell 進程 pid
ExecuteResultVO executeResultVO = executor.exec(String.format(GET_SHELL_PID,"sh /data/checkMysql.sh"));
//殺掉shell進程
ExecuteResultVO executeResultVO1 = executor.exec(String.format(KILL_SHELL_PID ,executeResultVO.getOutStr()));
}
public class ExecuteResultVO<T>{
private String outStr;
private String outErr;
//省略get set
}
}經過測試也確實好用啊,大家可以根據這個demo進行相應的修改。
感謝各位的閱讀!關于“java如何調用遠程服務器的shell腳本”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。