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) { } } }
本文来源:http://www.cnblogs.com/ylqmf/archive/2012/06/28/2567811.html
如果给你带来帮助,欢迎微信或支付宝扫一扫,赞一下。