天天看点

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

作者:从事java的小白

#头条创作挑战赛#

背景

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

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

三、实现调用

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