JAVA 实现 xshell 持续操作功能

JAVA 操作 linux 实现 xshell 持续操作功能


工作中让我去做一个类 Xshell 在页面显示的功能 经过 一些日子的 搜索资料 大概是找到了
记录上 学习链接 https://blog.csdn.net/sinadrew/article/details/79992986
https://www.cnblogs.com/lgfeng/p/3255535.html
主要通过这两篇文章 一步步摸索着写了出来 在这里插入图片描述
通过 长链接 ssh2 持续的 操作linux 数据库 现在 放上 代码
可以执行 基本的 操作命令 有一些修改文件的 内容是没法执行 sh脚本 可以使用

//      将链接 公共化  可能会出现问题  自己琢磨的
    public static ChannelShell channelShell;

    @RequestMapping("/addWindow")
    public Result goNewAddServer() {
//        开启一个session 链接 自定义的getSession 方法
        Session session = ShellUtils.getSession("192.168.200.XXX", "root", "root", 22);
        try{
//        链接session  设置session 长链接
            channelShell = ShellUtils.ChannelShell(session);
            return new Result(true,"");
        }catch (Exception e){
            return new Result(false,"");
        }

    }



    @RequestMapping("/linux")
    public ResultList getLinux(@RequestBody String cmd) throws UnsupportedEncodingException {
//        控制台 打印 模拟linux 黑窗口
        System.out.println("\n-----------------Linux Shell-----------------\n");
        System.out.println("执行命令: " + cmd);
        String res="";
//        判断 输入的命令  如果是 这三个 展示命令 会将 渲染的颜色取消  否则 变成 字符串 会出现乱码
        if(cmd.equals("ls") || cmd.equals("ll") ||cmd.equals("vi")){
            res = ShellUtils.executeNewFlow(channelShell, cmd +" --color=never"+ " \n");
            System.out.println(res);
        }else {
//            否则就正常输出命令
             res = ShellUtils.executeNewFlow(channelShell, cmd + " \n");

        }
//        遍历执行结果 按照 \r\n 分隔
        String[] str ={} ;
        str = res.split("\r\n");
        List<String>list = new ArrayList();
        for (String st:str){
            list.add(st);
        }
//            将结果返回给前台页面
            return new ResultList(true, list);

        }
package com.icbc.gateway.util;

import com.jcraft.jsch.*;

import java.io.*;

public class ShellUtils {

    /**
     * 创建session
     * @param host 主机名称/ip地址
     * @param user 登陆用户名
     * @param psw  密码
     * @param port 端口
     * @return
     */
    public static Session getSession(String host,String user,String psw,int port){
        JSch jsch=new JSch();
        Session session=null;
        try {
            session = jsch.getSession(user, host, port);
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.setPassword(psw);
            session.connect();
        } catch (JSchException e) {
            System.out.println("连接linux主机失败");
            e.printStackTrace();
        }
        return session;

    }
    /**
     * 得到可以执行命令的连接
     * @param session 连接session
     * @return 可以执行命令的ChannelExec
     */
    public static ChannelExec getChanel(Session session){
        ChannelExec openChannel=null;
        try {
            if(null !=session){
                openChannel = (ChannelExec) session.openChannel("exec");
            }
        } catch (JSchException e) {
            e.printStackTrace();
        }
        return openChannel;
    }
    /**
     * 
     * @param openChannel
     * @param command
     * @return
     */
    public static String getExcRes(ChannelExec openChannel,String command){
        InputStream in =null;
        BufferedReader reader=null;
        StringBuffer result=new StringBuffer();
        try {
            try {
                openChannel.setCommand(command);
                int exitStatus = openChannel.getExitStatus();
                System.out.println(exitStatus);
                openChannel.connect();
                in = openChannel.getInputStream();
                reader = new BufferedReader(new InputStreamReader(in));
                String buf = null;
                while ((buf = reader.readLine()) != null) {
                    result.append(new String(buf.getBytes("gbk"),"UTF-8")+"<br>\r\n");
                }
//reader.close();
            } catch (JSchException e) {
                result.append(e.getMessage());
                e.printStackTrace();
            }
        } catch (IOException e) {
            result.append(e.getMessage());
            e.printStackTrace();
        } /*finally {
//try {
//reader.close();
//} catch (IOException e) {
//e.printStackTrace();
//}
        }*/
        return result.toString();

    }

    public static ChannelShell ChannelShell(Session session) {
        ChannelShell channel = null;
        try {
            if (null != session) {
                channel = (ChannelShell) session.openChannel("shell");
                channel.connect();
            }
        } catch (JSchException e) {
            e.printStackTrace();
        }
        return channel;
    }


    public  static String executeNewFlow(ChannelShell channel, String command) {
        InputStream in =null;
        OutputStream out=null;
        String  msg=null;
        BufferedReader reader=null;
        StringBuffer result=new StringBuffer();
        try {
            in  =  channel.getInputStream();
            out =  channel.getOutputStream();
            out.write(command.getBytes());
            out.flush();
//            reader = new BufferedReader(new InputStreamReader(in));
//            while ((msg =reader.readLine()) !=null ){
//                System.out.println(msg);
//            }
            byte[] tmp=new byte[1024];
            while (true){
                int i=0;
                //线程等待 200ms
                Thread.currentThread().sleep(200);
                while(in.available()>0){
                    i=in.read(tmp, 0, 1024);
                    if(i<0)break;
                }
                System.out.print(new String(tmp, 0, i));
                return new String(tmp, 0, i);
//                if(channel.isClosed()){
//                    if(in.available()>0) continue;
//                    System.out.println("exit-status: "+channel.getExitStatus());
//                    break;
//                }
            }
        }catch (Exception e){
            result.append(e.getMessage());
            e.printStackTrace();
        }

        return null;
    }




    public static void disConnect(Session session,ChannelExec openChannel){
        if(session!=null&&!openChannel.isClosed()){
            openChannel.disconnect();
        }
        if(session!=null&&session.isConnected()){
            session.disconnect();
        }
    }


//    public static void main(String[] args) {
//        Session session=getSession("192.168.230.129", "root", "123456", 22);
//        ChannelExec chanel=getChanel(session);
//        String res=getExcRes(chanel, "cd /home;ls;");
//        System.out.println(res);
//        ChannelExec chanel2=getChanel(session);
//        String ss=getExcRes(chanel2, "ls;");
//        System.out.println(ss);
//    }

}

这是我借鉴来的 链接linux 方法 需要注意的 有两个
channel = (ChannelShell) session.openChannel(“shell”);
openChannel = (ChannelExec) session.openChannel(“exec”);
这两个地方开启的链接是不同的 一个是一次性链接 一个是 长链接 好像是 具体的有点忘记了

前台 使用的 是angular 还有 借鉴过来的 ajax 黑框口 使用的 layer.js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
    <link rel="stylesheet" type="text/css" href="../plugins/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="../plugins/adminLTE/css/AdminLTE.min.css">
    <link rel="stylesheet" type="text/css" href="../plugins/adminLTE/css/skins/_all-skins.min.css">

    <script src="../plugins/jQuery/jquery-2.2.3.min.js" ></script>
    <script src="../plugins/bootstrap/js/bootstrap.min.js" ></script>
    <script  src="../plugins/layer/layer.js"></script>

    <script src="../plugins/angularjs/angular.min.js"></script>
    <script src="../plugins/angularjs/pagination.js" ></script>
    <link rel="stylesheet" type="text/css" href="../plugins/angularjs/pagination.css" >

    <script>
        var app = angular.module('ICBC',[]);
        app.controller('gthController',function ($scope,$http) {

            $scope.addWindow = function () {
                $http.post('../gth/addWindow').success(
                   function (response) {
                       if(response.flag){
                           layer.open({
                               type: 2,
                               title: 'Linux 黑窗口',
                               maxmin: true,
                               shadeClose: true, //点击遮罩关闭层
                               area: ['800px', '520px'],
                               content: 'box1.html'
                           })
                       }
                   }

                )
            }

        });

    </script>

</head>
<body ng-app="ICBC" ng-controller="gthController">

<!--<a id="parentIframe"  class="layui-btn">运行上述例子</a>-->

<button id="parentIframe" ng-click="addWindow()" class="layui-btn">运行上述例子</button>
</body>
</html>

黑框口的设置 之前 可以随意修改 主体是一个input 框 每次 执行命令 将后台的结果 展示到append 到前台 展示


<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>命令行窗口</title>
    <script src="../plugins/jQuery/jquery-2.2.3.min.js" ></script>
    <script  src="../plugins/layer/layer.js"></script>

    <script src="../plugins/angularjs/angular.min.js"></script>
    <script src="../plugins/angularjs/pagination.js" ></script>
    <link rel="stylesheet" type="text/css" href="../plugins/angularjs/pagination.css" >

    <style type="text/css">
        body{
            background-color: #424242;  /*背景颜色*/
            font-size:14px;
        }


        .incmd {
            background-color: #9FB6CD; /*输入行颜色*/
            border: 0;
            color: #FFFFFF; /*输入字体颜色*/
            outline: none;
            font-size:14px;
            width: 99%;
        }

        .panel {/*暂时未用*/
            background-color: #424242;  /*背景颜色*/
            border-top: #424242 outset 2px;/*上边框*/
            width: 700px;
            height: 500px;
            overflow-y: scroll;
            overflow-x:visible;
            font-size:14px;

        }

        ul {
            margin: 0px;
            padding: 0px;
            list-style: none;
            color:#7CFC00; /*显示字体颜色*/
        }

        input {
            background-color: #9FB6CD; /*输入行颜色*/
            border: 0;
            color: #FFFFFF; /*输入字体颜色*/
            outline: none;
            font-size:14px;
            width: 99%;
        }
    </style>

    <script type="text/javascript">
        var app = angular.module('ICBC',[]);
        app.controller('gthController',function ($scope,$http) {

            $scope.linux = function($event){
                if($event.keyCode == 13){
                   $http.post('../gth/linux',$scope.entity).success(
                       function (response) {
                           if(response.flag==true) {

                               $("ul").append("<li>" +"输入的命令为:      "+ $scope.entity + "</li>"+"<br>");  //将输入的输出到界面

                               angular.forEach(response.message,function (data) {

                               $("ul").append("<li>" + data + "</li>"); //获取返回值并输出

                               })

                               $scope.entity=""; //清空输入框
                               $("#msg").scrollTop($("#msg").scrollTop() + 9999);//滚动条拉到最下面,显示出输入框
                           }
                           }
                   )

                }

            }
        })


        function CloseWebPage() {
            if (navigator.userAgent.indexOf("MSIE") > 0) {
                if (navigator.userAgent.indexOf("MSIE 6.0") > 0) {
                    window.opener = null;
                    window.close();
                } else {
                    window.open('', '_top');
                    window.top.close();
                }
            } else if (navigator.userAgent.indexOf("Firefox") > 0) {
                window.location.href = 'about:blank ';
            } else {
                window.opener = null;
                window.open('', '_self', '');
                window.close();
            }
        }
    </script>
</head>

<body ng-app="ICBC" ng-controller="gthController">
<div id="msg">
    <ul>
        <li>----------------------命令Demo----------------------------</li>
        <li>关闭进程方式1:</li>
        <li>    exit		//退出 进程</li>
        <li>----------------------开始操作----------------------------</li>
    </ul>

    <input type="text" ng-model="entity" value="$" ng-keypress="linux($event)" >
</div>

</body>

package com.icbc.gateway.pojo;

import java.io.Serializable;

public class Result implements Serializable {

    private  boolean flag;
    private  String message;

    @Override
    public String toString() {
        return "Result{" +
                "flag=" + flag +
                ", message='" + message + '\'' +
                '}';
    }


    public Result(boolean flag, String message) {
        super();
        this.flag = flag;
        this.message = message;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

就放全了吧 根据 要改的 linux 端口号 修改即可 jdk 1.8 ssh2 库
记录一下自己之前写的 不然隔几天就给忘记了

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值