`
krs
  • 浏览: 124728 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

[转]java连接SSH服务器并执行shell命令

    博客分类:
  • 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;

public class Shell {

    private static Logger log = Logger.getLogger(Shell.class);
    
    private Session session;
    private ChannelShell channel;
    private static Expect4j expect = null;
    private static final long defaultTimeOut = 1000;
    private StringBuffer buffer=new StringBuffer();
    
    public static final int COMMAND_EXECUTION_SUCCESS_OPCODE = -2;
    public static final String BACKSLASH_R = "\r";
    public static final String BACKSLASH_N = "\n";
    public static final String COLON_CHAR = ":";
    public static String ENTER_CHARACTER = BACKSLASH_R;
    public static final int SSH_PORT = 22;
    
    //正则匹配,用于处理服务器返回的结果
    public static String[] linuxPromptRegEx = new String[] { "~]#", "~#", "#",
            ":~#", "/$", ">" };
    
    public static String[] errorMsg=new String[]{"could not acquire the config lock "};
    
    //ssh服务器的ip地址
    private String ip;
    //ssh服务器的登入端口
    private int 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远程连接
     */
    public void 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();
        }
        return null;
    }

    /**
     * 执行配置命令
     * @param commands 要执行的命令,为字符数组
     * @return 执行是否成功
     */
    public boolean executeCommands(String[] commands) {
        //如果expect返回为0,说明登入没有成功
        if(expect==null){
            return false;
        }
        
        log.debug("----------Running commands are listed as follows:----------");
        for(String command:commands){
            log.debug(command);
        }
        log.debug("----------End----------");
        
        Closure closure = new Closure() {
            public void 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) {
                        return false;
                    } catch (Exception e) {
                        return false;
                    }
                }
                lstPattern.add(new EofMatch(new Closure() { // should cause
                                                            // entire page to be
                                                            // collected
                            public void run(ExpectState state) {
                            }
                        }));
                lstPattern.add(new TimeoutMatch(defaultTimeOut, new Closure() {
                    public void 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){
                    return false;
                }
            }
            
            return isSuccess;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

    //检查执行是否成功
    private boolean isSuccess(List<Match> objPattern, String strCommandPattern) {
        try {
            boolean isFailed = checkResult(expect.expect(objPattern));
            if (!isFailed) {
                expect.send(strCommandPattern);
                expect.send("\r");
                return true;
            }
            return false;
        } catch (MalformedPatternException ex) {
            return false;
        } catch (Exception ex) {
            return false;
        }
    }

    //检查执行返回的状态
    private boolean checkResult(int intRetVal) {
        if (intRetVal == COMMAND_EXECUTION_SUCCESS_OPCODE) {
            return true;
        }
        return false;
    }
    
    //登入SSH时的控制信息
    //设置不提示输入密码、不显示登入信息等
    public static class localUserInfo implements UserInfo {
        String passwd;

        public String getPassword() {
            return passwd;
        }

        public boolean promptYesNo(String str) {
            return true;
        }

        public String getPassphrase() {
            return null;
        }

        public boolean promptPassphrase(String message) {
            return true;
        }

        public boolean promptPassword(String message) {
            return true;
        }

        public void showMessage(String message) {
            
        }
    }

}

 

(转自:http://www.cnblogs.com/flyingzl/articles/2145032.html

分享到:
评论

相关推荐

    java通过ssh连接服务器执行shell命令详解及实例

    主要介绍了java通过ssh连接服务器执行shell命令详解及实例方法的相关资料

    java调用shell命令实现实例

    基于sshConnect的linux服务器的shell命令调用,并获取命令返回结果的实例。亲测有效!

    java控制台输入cmd命令, ssh远程linux shell命令, 并打印命令输出到控制台

    本地cmd命令, 输入命令, 并在控制台输出命令执行结果 jsch 远程ssh到linux服务器, 执行结果并显示输出

    ganymed-ssh2 远程连接java实例代码

    Ganymed SSH-2支持SSH对话(远程命令执行和shell访问),本地和远程端口转发,本地数据流转发,X11转发和SCP。这些都没有依赖任何JCE provider,而且所有这些都包含加密的功能。该资源是java远程连接ssh服务器的实例...

    linux shell的java操作实现

    通过linux的SSH端口使用java代码远程对指定的linux服务器上执行shell命令,实测有用

    shell-exec-java-server

    shell-exec-java-server描述使用这个服务器,你可以访问远程服务器并执行shell命令例如)你会丢失ssh密钥,但不要担心。 保持此服务器正常工作意味着您有后门。用法第一步更改运行此程序的端口。 public static ...

    java连接linux

    java连接linux服务器,并且可以做各种操作。内部使用多线程处理,可以持续与linux服务器进行交互操作,完全跟使用ssh客户端一样。

    ganymed-ssh2-build210

    可以利用它直接在Java程序中连接SSH服务器。Ganymed SSH-2支持SSH对话(远程命令执行和shell访问),本地和远程端口转发,本地数据流转发,X11转发和SCP。这些都没有依赖任何JCE provider,而且所有这些都包含加密的...

    jvm-ssh-groovy-shell:通过 SSH 连接到您的 JVM 并使用 Groovy Shell 以交互方式控制您的代码

    使用此集成,您可以快速将 SSH 服务器添加到您的应用程序,并能够远程访问 Groovy shell,让您在正在运行的 JVM 中以交互方式运行代码。 换句话说,它是一个可远程访问的 REPL,位于您的 JVM 中,从而允许您检查...

    jsch.jar 工具类,在java中通过使用本工具可以使用shell远程控制服务器

    jsch工具类,在java中通过使用本工具可以使用... 具体操作可以看我的博客,《java通过shell命令远程操作服务器(SSH)》,里面保护jar包源码jar包,demo: https://blog.csdn.net/qq_27731689/article/details/103696288

    java开源包4

    WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 ...

    JAVA上百实例源码以及开源项目

     基于JAVA的UDP服务器模型源代码,内含UDP服务器端模型和UDP客户端模型两个小程序,向JAVA初学者演示UDP C/S结构的原理。 简单聊天软件CS模式 2个目标文件 一个简单的CS模式的聊天软件,用socket实现,比较简单。 ...

    JAVA上百实例源码以及开源项目源代码

     基于JAVA的UDP服务器模型源代码,内含UDP服务器端模型和UDP客户端模型两个小程序,向JAVA初学者演示UDP C/S结构的原理。 简单聊天软件CS模式 2个目标文件 一个简单的CS模式的聊天软件,用socket实现,比较简单。 ...

    java_jsp项目源码_移动ssh项目(struts+spring+hibernate+oracle).rar

    移动SSH项目是一个基于Struts、Spring、Hibernate和Oracle技术栈的企业级Java Web应用,它为企业提供了一套完整的移动端SSH(Secure Shell)解决方案。项目具有高度可定制性,可以根据客户需求进行二次开发和定制。...

    java开源包11

    WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 ...

    java开源包6

    WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 ...

    java开源包9

    WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 ...

    java开源包101

    WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 ...

    java开源包5

    WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 ...

    java开源包8

    WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 ...

Global site tag (gtag.js) - Google Analytics