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;    
}

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

相关文章
|
7月前
|
Java Linux Apache
Apache NetBeans 27 (macOS, Linux, Windows) - Java 等多语言开源跨平台 IDE
Apache NetBeans 27 (macOS, Linux, Windows) - Java 等多语言开源跨平台 IDE
417 5
Apache NetBeans 27 (macOS, Linux, Windows) - Java 等多语言开源跨平台 IDE
|
9月前
|
Java Linux 开发者
linux 查看java的安装路径
本指南详细介绍Java环境的安装验证与配置方法,包括检查Java版本、确认环境变量JAVA_HOME是否正确配置,以及通过which和readlink命令手动定位Java安装路径。同时提供系统级环境变量配置步骤,并给出多版本管理建议。适用于Linux系统用户,特别是需要在服务器或Docker容器中部署Java环境的开发者。注意操作时需具备相应权限,确保路径设置准确无误。
|
10月前
|
Ubuntu Linux 网络安全
在Linux云服务器上限制特定IP进行SSH远程连接的设置
温馨提示,修改iptables规则时要格外小心,否则可能导致无法远程访问你的服务器。最好在掌握足够技术知识和理解清楚操作含义之后再进行。另外,在已经配置了防火墙的情况下,例如ufw(Ubuntu Firewall)或firewalld,需要按照相应的防火墙的规则来设置。
520 24
|
11月前
|
监控 数据可视化 Java
调试技巧 - 用Linux命令排查Java问题
总的来说,使用Linux命令来排查Java问题,需要一定的实践经验和理论知识。然而,只要我们愿意花时间深入了解这些工具,我们就能够熟练地使用它们来分析和解决问题。此外,这些工具只是帮助我们定位问题,真正解决问题需要我们对Java和JVM有深入的理解,并能够读懂和分析代码。
565 13
|
分布式计算 Java Hadoop
linux中HADOOP_HOME和JAVA_HOME删除后依然指向旧目录
通过以上步骤,可以有效地解决 `HADOOP_HOME`和 `JAVA_HOME`删除后依然指向旧目录的问题。确保在所有相关的配置文件中正确设置和删除环境变量,并刷新当前会话,使更改生效。通过这些措施,能够确保系统环境变量的正确性和一致性。
314 1
|
Web App开发 搜索推荐 Unix
Linux系统之MobaXterm远程连接centos的GNOME桌面环境
【10月更文挑战第21天】Linux系统之MobaXterm远程连接centos的GNOME桌面环境
2760 5
Linux系统之MobaXterm远程连接centos的GNOME桌面环境
|
运维 Java Linux
【运维基础知识】Linux服务器下手写启停Java程序脚本start.sh stop.sh及详细说明
### 启动Java程序脚本 `start.sh` 此脚本用于启动一个Java程序,设置JVM字符集为GBK,最大堆内存为3000M,并将程序的日志输出到`output.log`文件中,同时在后台运行。 ### 停止Java程序脚本 `stop.sh` 此脚本用于停止指定名称的服务(如`QuoteServer`),通过查找并终止该服务的Java进程,输出操作结果以确认是否成功。
1070 1
|
5月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
274 1
|
5月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
294 1