java 整合jsch使用 远程交互服务器

createh52个月前 (02-01)技术教程11

#头条创作挑战赛#

背景

java 通过jsch 远程执行命令 jsch 主要是类似Xshell 只不过是代码级别使用,而 Xshell使用界面化

jsch可以执行任何shell 脚本,但是弊端是执行一次必须要关闭当前会话,每次都要cd当前目录
在执行相关命令,都是操作 channle 同时写了一个cmd执行方法为的是执行linux命令
setCommand(…) 这个方法是比较重要的 session就是维护你当前会话和服务器进行交流的

channle相当于管道流,数据交互用的

一、导入相关的依赖包

<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.54</version>
</dependency>

二、实现相关的工具类

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

@Slf4j
public class ShellUtil {

    private String host;
    private String username;
    private String password;
    private int port = 22;
    private int timeout = 60 * 60 * 1000;

    public ShellUtil(String host, String username, String password, int port, int timeout) {
        this.host = host;
        this.username = username;
        this.password = password;
        this.port = port;
        this.timeout = timeout;
    }

    public ShellUtil(String host, String username, String password) {
        this.host = host;
        this.username = username;
        this.password = password;
    }

    public Session createSession() throws JSchException {
        JSch jSch = new JSch();
        // 1. 获取 ssh session
        Session session = jSch.getSession(username, host, port);
        session.setPassword(password);
        session.setTimeout(timeout);
        //StrictHostKeyChecking=no 最不安全的级别,当然也没有那么多烦人的提示了,相对安全的内网测试时建议使用
        //如果连接server的key在本地不存在,那么就自动添加到文件中(默认是known_hosts),并且给出一个警告。
        //StrictHostKeyChecking=ask 默认的级别,就是出现刚才的提示了。如果连接和key不匹配,给出提示,并拒绝登录。
        //StrictHostKeyChecking=yes 最安全的级别,如果连接与key不匹配,就拒绝连接,不会提示详细信息。
        session.setConfig("StrictHostKeyChecking", "no");
        // 获取到 ssh session
        session.connect();
        return session;
    }

    public String execCommand(String cmd) {
        Session session = null;
        ChannelExec channelExec = null;
        BufferedReader inputStreamReader = null;
        BufferedReader errInputStreamReader = null;
        StringBuilder runLog = new StringBuilder("");
        StringBuilder errLog = new StringBuilder("");
        try {
            session = createSession();

            // 2. 通过 exec 方式执行 shell 命令
            channelExec = (ChannelExec) session.openChannel("exec");
            channelExec.setCommand(cmd);
            // 执行命令
            channelExec.connect();

            // 3. 获取标准输入流
            inputStreamReader = new BufferedReader(new 
                                                   InputStreamReader(channelExec.getInputStream()));
            // 4. 获取标准错误输入流
            errInputStreamReader = new BufferedReader(new 
                                                      InputStreamReader(channelExec.getErrStream()));

            // 5. 记录命令执行 log
            String line;
            while ((line = inputStreamReader.readLine()) != null) {
                runLog.append(line).append("\n");
            }

            // 6. 记录命令执行错误 log
            String errLine;
            while ((errLine = errInputStreamReader.readLine()) != null) {
                errLog.append(errLine).append("\n");
            }

            // 7. 输出 shell 命令执行日志
            log.info("exitStatus={},openChannel.isClosed={}", channelExec.getExitStatus(), channelExec.isClosed());
            log.info("命令执行完成,执行日志如下:{}", runLog.toString());
            log.info("命令执行完成,执行错误日志如下:{}", errLog.toString());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (!StringUtils.isEmpty(inputStreamReader)) {
                    inputStreamReader.close();
                }
                if (!StringUtils.isEmpty(errInputStreamReader)) {
                    errInputStreamReader.close();
                }

                if (!StringUtils.isEmpty(channelExec)) {
                    channelExec.disconnect();
                }
                if (!StringUtils.isEmpty(session)) {
                    session.disconnect();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return runLog.toString();
    }

}


三、实现调用

String shCmd = "sh /xxx/xxx/syncFile.sh";
//执行调用脚本执行
ShellUtil shellUtil = new ShellUtil("ip", "username", "password");
String execLog = shellUtil.execCommand(shCmd);
log.info(execLog);

相关文章

Arduino通过串口透传ESP 13板与java程序交互

ESP 13 --- 是一个无线板子,配置通过热点通信Arduino通过串口透传ESP13板与java程序交互这个程序最基本的想法是用java把Arduino抽象出来,忙活了好几天,虽然没有达到最后的...

Java 24 功能已冻结,进入 Rampdown 第二阶段

作者 | Tim Anderson 译者 | 王强 策划 | TinaOracle 的 Java 平台首席架构师 Mark Reinhold 宣布 JDK 24 已处于 Rampdown 第二阶段,这...

基于JAVA的社交聊天室(基于java的社交聊天室设计方案)

基于Java的社交聊天室一、前言随着互联网技术的迅速发展,实时通信和在线社交已成为人们日常生活的重要组成部分。基于Java的社交聊天室系统,凭借其跨平台、高性能和安全性等特点,为用户提供了一个集中、开...

Java-IO流(Javaio流最快多少mb每秒上传)

目录1、流的概念和作用1.2、Java IO所采用的模型1.3、IO流的分类1.4、IO流特性1.5、IO流常用到的五类一接口1.6、Java IO流对象1.6.1、输入字节流InputStream1...

Jcef 例子4_JCEF中js与java交互、js与java相互调用

调用jcef核心代码CefMessageRouter msgRouter = CefMessageRouter.create(new CefMessageRouter.CefMessageRouter...

反向 Debug 了解一下?揭秘 Java DEBUG 的基本原理

作者:保险业务部 蒋信点赞再看,养成习惯Debug 的时候,都遇到过手速太快,直接跳过了自己想调试的方法、代码的时候吧……一旦跳过,可能就得重新执行一遍,准备数据、重新启动可能几分钟就过去了。好在ID...