java通過ssh登陸執行linux命令

來源:互聯網
上載者:User
package com.flyingzl.ssh;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.oro.text.regex.MalformedPatternException;

import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;


import expect4j.Closure;
import expect4j.Expect4j;
import expect4j.ExpectState;
import expect4j.matches.EofMatch;
import expect4j.matches.Match;
import expect4j.matches.RegExpMatch;
import expect4j.matches.TimeoutMatch;

publicclass Shell {

privatestatic Logger log = Logger.getLogger(Shell.class);

private Session session;
private ChannelShell channel;
privatestatic Expect4j expect =null;
privatestaticfinallong defaultTimeOut =1000;
private StringBuffer buffer=new StringBuffer();

publicstaticfinalint COMMAND_EXECUTION_SUCCESS_OPCODE =-2;
publicstaticfinal String BACKSLASH_R ="\r";
publicstaticfinal String BACKSLASH_N ="\n";
publicstaticfinal String COLON_CHAR =":";
publicstatic String ENTER_CHARACTER = BACKSLASH_R;
publicstaticfinalint SSH_PORT =22;

//正則匹配,用於處理伺服器返回的結果
publicstatic String[] linuxPromptRegEx =new String[] { "~]#", "~#", "#",
":~#", "/$", ">" };

publicstatic String[] errorMsg=new String[]{"could not acquire the config lock "};

//ssh伺服器的ip地址
private String ip;
//ssh伺服器的登入連接埠
privateint port;
//ssh伺服器的登入使用者名稱
private String user;
//ssh伺服器的登入密碼
private String password;

public Shell(String ip,int port,String user,String password) {
this.ip=ip;
this.port=port;
this.user=user;
this.password=password;
expect = getExpect();
}

/**
* 關閉SSH遠端連線
*/
publicvoid disconnect(){
if(channel!=null){
channel.disconnect();
}
if(session!=null){
session.disconnect();
}
}

/**
* 擷取伺服器返回的資訊
* @return 服務端的執行結果
*/
public String getResponse(){
return buffer.toString();
}

//獲得Expect4j對象,該對用可以往SSH發送命令請求
private Expect4j getExpect() {
try {
log.debug(String.format("Start logging to %s@%s:%s",user,ip,port));
JSch jsch =new JSch();
session = jsch.getSession(user, ip, port);
session.setPassword(password);
Hashtable<String, String> config =new Hashtable<String, String>();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
localUserInfo ui =new localUserInfo();
session.setUserInfo(ui);
session.connect();
channel = (ChannelShell) session.openChannel("shell");
Expect4j expect =new Expect4j(channel.getInputStream(), channel
.getOutputStream());
channel.connect();
log.debug(String.format("Logging to %s@%s:%s successfully!",user,ip,port));
return expect;
} catch (Exception ex) {
log.error("Connect to "+ip+":"+port+"failed,please check your username and password!");
ex.printStackTrace();
}
returnnull;
}

/**
* 執行配置命令
* @param commands 要執行的命令,為字元數組
* @return 執行是否成功
*/
publicboolean executeCommands(String[] commands) {
//如果expect返回為0,說明登入沒有成功
if(expect==null){
returnfalse;
}

log.debug("----------Running commands are listed as follows:----------");
for(String command:commands){
log.debug(command);
}
log.debug("----------End----------");

Closure closure =new Closure() {
publicvoid run(ExpectState expectState) throws Exception {
buffer.append(expectState.getBuffer());// buffer is string
// buffer for appending
// output of executed
// command
expectState.exp_continue();

}
};
List<Match> lstPattern =new ArrayList<Match>();
String[] regEx = linuxPromptRegEx;
if (regEx !=null&& regEx.length >0) {
synchronized (regEx) {
for (String regexElement : regEx) {// list of regx like, :>, />
// etc. it is possible
// command prompts of your
// remote machine
try {
RegExpMatch mat =new RegExpMatch(regexElement, closure);
lstPattern.add(mat);
} catch (MalformedPatternException e) {
returnfalse;
} catch (Exception e) {
returnfalse;
}
}
lstPattern.add(new EofMatch(new Closure() { // should cause
// entire page to be
// collected
publicvoid run(ExpectState state) {
}
}));
lstPattern.add(new TimeoutMatch(defaultTimeOut, new Closure() {
publicvoid run(ExpectState state) {
}
}));
}
}
try {
boolean isSuccess =true;
for (String strCmd : commands){
isSuccess = isSuccess(lstPattern, strCmd);
}
//防止最後一個命令執行不了
isSuccess =!checkResult(expect.expect(lstPattern));

//找不到錯誤資訊標示成功
String response=buffer.toString().toLowerCase();
for(String msg:errorMsg){
if(response.indexOf(msg)>-1){
returnfalse;
}
}

return isSuccess;
} catch (Exception ex) {
ex.printStackTrace();
returnfalse;
}
}

//檢查執行是否成功
privateboolean isSuccess(List<Match> objPattern, String strCommandPattern) {
try {
boolean isFailed = checkResult(expect.expect(objPattern));
if (!isFailed) {
expect.send(strCommandPattern);
expect.send("\r");
returntrue;
}
returnfalse;
} catch (MalformedPatternException ex) {
returnfalse;
} catch (Exception ex) {
returnfalse;
}
}

//檢查執行返回的狀態
privateboolean checkResult(int intRetVal) {
if (intRetVal == COMMAND_EXECUTION_SUCCESS_OPCODE) {
returntrue;
}
returnfalse;
}

//登入SSH時的控制資訊
//設定不提示輸入密碼、不顯示登入資訊等
publicstaticclass localUserInfo implements UserInfo {
String passwd;

public String getPassword() {
return passwd;
}

publicboolean promptYesNo(String str) {
returntrue;
}

public String getPassphrase() {
returnnull;
}

publicboolean promptPassphrase(String message) {
returntrue;
}

publicboolean promptPassword(String message) {
returntrue;
}

publicvoid showMessage(String message) {

}
}

}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.