zoukankan      html  css  js  c++  java
  • java通过ssh登陆执行linux命令

    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) {

    }
    }

    }
  • 相关阅读:
    一个神奇的类库,可以执行字符串表达式
    Common lang一些边界方法总结(好记性不如烂笔头,需要慢慢积累).一定要利用好现有的轮子,例如Apache common与Google Guava
    借助强大的IDEA开发ide高效实现equals,hashcode以及toString方法
    数字签名是什么?
    字符串组合
    空格替换
    字符串替换 (replace)
    为什么要区分稳定和非稳定排序
    算法稳定性
    华为2018校招技术岗笔试
  • 原文地址:https://www.cnblogs.com/ylqmf/p/2567811.html
Copyright © 2011-2022 走看看