在 Java 中可以通過 SSH2 協定遠端執行 Linux 系統的指令或 Shell 腳本。
1. 添加依賴
需添加 ganymed-ssh2-build210.jar 包,Maven 依賴如下:
<dependency>
<groupId>com.ganymed.ssh2</groupId>
<artifactId>ganymed-ssh2-build</artifactId>
<version>210</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. 執行個體代碼
/**
* @ClassName: RemoteExecuteCommand
* @Description: 遠端執行Linux指令
* @date: 2017年10月9日 下午5:44:42
*/
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();
}
測試
public static void main(String[] args) {
String linuxIP = "192.168.X.XXX";
String usrName = "root";
String passwd = "******";
RemoteExecuteCommand rec = new RemoteExecuteCommand(linuxIP, usrName, passwd);
// 執行指令
System.out.println(rec.execute("ifconfig"));
// 執行腳本
rec.execute("sh /usr/local/tomcat/bin/statup.sh");
}
參考:
java遠端調用linux的指令或者腳本