1. 程式人生 > >ssh client 程式執行命令

ssh client 程式執行命令

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 %[email protected]%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 %[email protected]%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 machinetry { 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 // collectedpublicvoid 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) { } } }