Java使用jsch和expect4j執行Linux命令

1.背景

    最近項目上需要遠程鏈接至Linxu服務器執行語句,所以自己研究了下,找到了幾個開源框架,並且稍微封裝了一個Until類,供大家參考。

2.準備工作

    Pom文件引入依賴

​<dependency>

    <groupId>com.jcraft</groupId>

    <artifactId>jsch</artifactId>

    <version>0.1.54</version>

</dependency>

<dependency>

    <groupId>com.github.cverges</groupId>

    <artifactId>expect4j</artifactId>

    <version>1.9</version>

</dependency>

3.工具類分享

import com.jcraft.jsch.ChannelShell;

import com.jcraft.jsch.JSch;

import com.jcraft.jsch.Session;

import expect4j.Expect4j;

import expect4j.matches.EofMatch;

import expect4j.matches.Match;

import expect4j.matches.RegExpMatch;

import expect4j.matches.TimeoutMatch;

import org.apache.oro.text.regex.MalformedPatternException;

import org.springframework.stereotype.Component;

 

import java.util.ArrayList;

import java.util.Hashtable;

import java.util.List;

 

/**

 * 執行shell語句工具類

 */

@Component

public class CMDUtilShell {

    private static final int COMMAND_EXECUTION_SUCCESS_OPCODE = -2;

    private static final String BACKSLASH_R = "\r";

 

    /**

     * 執行配置命令

     *

     * @param commands 要執行的命令,爲字符數組

     * @return 執行是否成功

     */

    public String executeCommands(String[] commands, String ip, int port, String user, String password ,Integer sshTimeout) {

        Session session = null;

        ChannelShell channel = null;

        Expect4j expect = null;

        try {

            session = new JSch().getSession(user, ip, port);

            session.setPassword(password);

            session.setConfig(bulidConfig());

            // 設置不提示輸入密碼、不顯示登入信息等

            session.setUserInfo(new LocalUserInfo());

            session.connect();

            channel = (ChannelShell) session.openChannel("shell");

            expect = new Expect4j(channel.getInputStream(), channel.getOutputStream());

            channel.connect(sshTimeout+1000);

            // 存放返回值

            StringBuffer buffer = new StringBuffer();

            // 執行語句

            List<Match> lstPattern = bulidPattern(buffer, sshTimeout);

            for (String strCmd : commands) {

                if (expect.expect(lstPattern) != COMMAND_EXECUTION_SUCCESS_OPCODE) {

                    expect.send(strCmd);

                    expect.send(BACKSLASH_R);

                }

            }

            expect.expect(lstPattern);

            return buffer.toString().toLowerCase();

        } catch (Exception ex) {

            String errorMsg = String.format("[@CMDUtilShell] host=[%s] user=[%s] [error=%s]", ip, user, ex.getMessage());

        } finally {

            if (expect != null) {

                expect.close();

            }

            if (channel != null) {

                channel.disconnect();

            }

            if (session != null) {

                session.disconnect();

            }

        }

    }

 

    /**

     * 構建配置項

     */

    private Hashtable<String, String> bulidConfig() {

        Hashtable<String, String> config = new Hashtable<>();

        config.put("userauth.gssapi-with-mic", "no");

        config.put("StrictHostKeyChecking", "no");

        return config;

    }

 

    /**

     * 構建模式

     */

    private List<Match> bulidPattern(StringBuffer buffer,Integer sshTimeout) throws MalformedPatternException {

        List<Match> lstPattern = new ArrayList<>();

        // 終止符

        // todo:存入數據庫使用參數配置

        String[] regEx = { "~]#", "~#", ":~#", };

        for (String regexElement : regEx) {

            RegExpMatch mat = new RegExpMatch(regexElement, x -> {

                buffer.append(x.getBuffer());

            });

            lstPattern.add(mat);

        }

 

        lstPattern.add(new EofMatch(x -> {

        }));

        // 設置超時時間

        lstPattern.add(new TimeoutMatch(sshTimeout, x -> {

        }));

 

        return lstPattern;

    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章