天天看點

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