1.背景
最近项目上需要远程链接至Linxu服务器执行语句,所以自己研究了下,找到了几个开源框架,并且稍微封装了一个Until类,供大家参考。
2.准备工作
Pom文件引入依赖
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.54</version> </dependency> <dependency> <groupId>com.github.cverges</groupId> <artifactId>expect4j</artifactId> <version>1.9</version> </dependency> |
3.工具类分享
import com.jcraft.jsch.ChannelShell; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import expect4j.Expect4j; import expect4j.matches.EofMatch; import expect4j.matches.Match; import expect4j.matches.RegExpMatch; import expect4j.matches.TimeoutMatch; import org.apache.oro.text.regex.MalformedPatternException; import org.springframework.stereotype.Component;
import java.util.ArrayList; import java.util.Hashtable; import java.util.List;
/** * 执行shell语句工具类 */ @Component public class CMDUtilShell { private static final int COMMAND_EXECUTION_SUCCESS_OPCODE = -2; private static final String BACKSLASH_R = "\r";
/** * 执行配置命令 * * @param commands 要执行的命令,为字符数组 * @return 执行是否成功 */ public String executeCommands(String[] commands, String ip, int port, String user, String password ,Integer sshTimeout) { Session session = null; ChannelShell channel = null; Expect4j expect = null; try { session = new JSch().getSession(user, ip, port); session.setPassword(password); session.setConfig(bulidConfig()); // 设置不提示输入密码、不显示登入信息等 session.setUserInfo(new LocalUserInfo()); session.connect(); channel = (ChannelShell) session.openChannel("shell"); expect = new Expect4j(channel.getInputStream(), channel.getOutputStream()); channel.connect(sshTimeout+1000); // 存放返回值 StringBuffer buffer = new StringBuffer(); // 执行语句 List<Match> lstPattern = bulidPattern(buffer, sshTimeout); for (String strCmd : commands) { if (expect.expect(lstPattern) != COMMAND_EXECUTION_SUCCESS_OPCODE) { expect.send(strCmd); expect.send(BACKSLASH_R); } } expect.expect(lstPattern); return buffer.toString().toLowerCase(); } catch (Exception ex) { String errorMsg = String.format("[@CMDUtilShell] host=[%s] user=[%s] [error=%s]", ip, user, ex.getMessage()); } finally { if (expect != null) { expect.close(); } if (channel != null) { channel.disconnect(); } if (session != null) { session.disconnect(); } } }
/** * 构建配置项 */ private Hashtable<String, String> bulidConfig() { Hashtable<String, String> config = new Hashtable<>(); config.put("userauth.gssapi-with-mic", "no"); config.put("StrictHostKeyChecking", "no"); return config; }
/** * 构建模式 */ private List<Match> bulidPattern(StringBuffer buffer,Integer sshTimeout) throws MalformedPatternException { List<Match> lstPattern = new ArrayList<>(); // 终止符 // todo:存入数据库使用参数配置 String[] regEx = { "~]#", "~#", ":~#", }; for (String regexElement : regEx) { RegExpMatch mat = new RegExpMatch(regexElement, x -> { buffer.append(x.getBuffer()); }); lstPattern.add(mat); }
lstPattern.add(new EofMatch(x -> { })); // 设置超时时间 lstPattern.add(new TimeoutMatch(sshTimeout, x -> { }));
return lstPattern; } } |