java远程连接linux

简介: 主要解决执行su命令时异常卡住

最近在公司项目中,需用java远程连接linux服务器。最终选定了用jsch的方式。但在实现的过程中遇到两个问题。
①通过jsch的exec通道时,执行su命令会异常开始,原因是因为执行su命令后返回的结果标准化输出后为空,所以异常卡死;最后放弃此种方式改用shell通道
②使用jsch的shell通道时,如何获取到返回结果。通过readline的方式读取时执行su依旧会进入死循环,最后决定通过读取字节码的方式来获取返回结果,通过字节码的方式读取时又遇到终端显示字体颜色的乱码问题,通过设置伪终端的方式解决。
一下为解决的代码:
首先创建会话:
public static Session createSession(String OSIP, String OSUserName, String OSPassword){

    
    Session session = null;
    JSch jsch = new JSch();    
    try {
         // 通过jsch创建一个会话
         session = jsch.getSession(OSUserName, OSIP, port);
         // 设置会话自动传输密码
         session.setPassword(OSPassword);
         // 创建Properties类
         Properties config = new Properties();
         // 设置第一次登录不验证密码
         config.put("StrictHostKeyChecking", "no");
         // 设置公钥和私钥
         config.put("PreferredAuthentications", "publickey,keyboard-interactive,password");
         // 导入会话设置
         session.setConfig(config);
         // 设置会话超时时间
         session.setTimeout(timeOut);
         Log.printLog("ssh连接" + OSIP);
         // 连接上目标IP的会话
         session.connect();
         //代码调试,信息打印
         //System.out.println("username"+session.getUserName()+session.isConnected());
    } catch (JSchException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return session;
    
}

建议交互式shell通道:

public static ChannelShell createChannelShell(Session session) {
    ChannelShell channelShell = null;
    try {
        Channel channel = session.openChannel("shell");
        channelShell = (ChannelShell) channel;
        //解决终端高亮显示时颜色乱码问题
        channelShell.setPtyType("dump");
        channelShell.setPty(true);
        channelShell.connect();
        Log.printLog("与" + session.getHost() + "的SHELL通道建立成功");
    } catch (JSchException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return channelShell;
    
}

执行命令:

public static String execShellCmd(ChannelShell channelShell, String command, int sleepTime){

    StringBuffer sBuffer = new StringBuffer();
    int beat = 0;
    String result = "";
    String endResult = "";
    try {
        // 远端界面返回
        InputStream in = channelShell.getInputStream();
        // 本地内容推送到远端
        OutputStream out = channelShell.getOutputStream();
        // 要执行命令后加换行符才可以执行
        String execCommand = command + changeLine;
        Log.printLog("要执行的命令:" + command);
        // 写入执行命令
        out.write(execCommand.getBytes());
        // 清空缓存区,开始执行
        out.flush();
        Thread.sleep(sleepTime);             
        while (true) {
            if (beat > 3) {
                break;
            }
            if (in.available() >0 ) {      
                //InputStream按位读取,并保存在stringbuffer中
                   byte[] bs =new byte[in.available()];
                   in.read(bs);
                   sBuffer.append(new String(bs));
                   beat ++;
               }else {                   
                   if (sBuffer.length() >0) {
                    beat++;
                }
               }
        }
        // 将stringbuff读取的InputStream数据,转换成特定编码格式的字符串,一般为UTF-8格式
        result = new String(sBuffer.toString().getBytes(charsetName));
        
        // 将返回结果,按行截取并放进数组里面
        String[] strings = result.split(changeLine);
        
        // 通过遍历,筛选无意义的字符
        for (int i = 1; i < strings.length; i++) {
            if (!strings[i].contains("#") && !strings[i].contains(command) &&
                !strings[i].contains("$") && !strings[i].contains(">")) {
                //获取筛选后的字符
                endResult = endResult+strings[i] +changeLine;
            }
        }
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
    }
    Log.printLog("命令执行完,返回的结果为:" + endResult);
    return endResult;    
}

其实在结果返回的处理这部分。代码逻辑有点混乱。但是能用。感觉处理的不是很好。也请各位帮忙能优化下。

相关文章
|
21天前
|
Web App开发 搜索推荐 Unix
Linux系统之MobaXterm远程连接centos的GNOME桌面环境
【10月更文挑战第21天】Linux系统之MobaXterm远程连接centos的GNOME桌面环境
175 4
Linux系统之MobaXterm远程连接centos的GNOME桌面环境
|
1月前
|
算法 Java Linux
java制作海报七:java Graphics2D 合成图片 在 linux下中文不显示,echarts图上的中文也不显示问题
这篇文章讨论了在Linux环境下使用Java Graphics2D合成图片时遇到的中文显示问题,并提供了解决方案,包括如何在Linux系统中添加中文字体库。
33 1
java制作海报七:java Graphics2D 合成图片 在 linux下中文不显示,echarts图上的中文也不显示问题
|
1月前
|
Java Linux
java读取linux服务器下某文档的内容
java读取linux服务器下某文档的内容
36 3
java读取linux服务器下某文档的内容
|
1月前
|
运维 Java Linux
【运维基础知识】Linux服务器下手写启停Java程序脚本start.sh stop.sh及详细说明
### 启动Java程序脚本 `start.sh` 此脚本用于启动一个Java程序,设置JVM字符集为GBK,最大堆内存为3000M,并将程序的日志输出到`output.log`文件中,同时在后台运行。 ### 停止Java程序脚本 `stop.sh` 此脚本用于停止指定名称的服务(如`QuoteServer`),通过查找并终止该服务的Java进程,输出操作结果以确认是否成功。
35 1
|
1月前
|
算法 Java Linux
java制作海报五:java 后端整合 echarts 画出 折线图,项目放在linux上,echarts图上不显示中文,显示方框口口口
这篇文章介绍了如何在Java后端整合ECharts库来绘制折线图,并讨论了在Linux环境下ECharts图表中文显示问题。
39 1
|
2月前
|
消息中间件 分布式计算 Java
Linux环境下 java程序提交spark任务到Yarn报错
Linux环境下 java程序提交spark任务到Yarn报错
41 5
|
2月前
|
Oracle Java 关系型数据库
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
如果遇到"exec format error"问题,文章建议先检查Linux操作系统是32位还是64位,并确保安装了与系统匹配的JDK版本。如果系统是64位的,但出现了错误,可能是因为下载了错误的JDK版本。文章提供了一个链接,指向Oracle官网上的JDK 17 Linux版本下载页面,并附有截图说明。
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
|
1月前
|
Java Linux Maven
用sdkman在linux上管理多个java版本
本文介绍了如何在Linux上使用SDKMAN来管理多个Java版本,包括安装SDKMAN、验证安装、列出和安装不同版本的JDK、Maven和Gradle,以及如何切换使用不同版本。
49 0
|
关系型数据库 MySQL Linux
Linux下yum安装mysql以及设置远程连接
Linux下yum安装mysql以及设置远程连接 一、Liniux下yum安装mysql 1、下载 mysql mysql-server yum install mysql mysql-server 12、启动mysql service mysqld start 13、设置mysql 超.
2116 0
|
4天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
19 3