远程连接SSh,可以配合webhook使用,自动打包处理,在docker部署下,是一种成本很小但是很实用的方案。

本方案使用ssh2进行链接。正常来说有两种链接方式,这里选择startShell,这种方式更像是新开一个terminal,可以取到完整的系统变量,脚本才能正常执行。另一种方案因为加载问题,取不到完整变量,导致部分语句执行失败。

上代码,pom

<dependency>
  <groupId>ch.ethz.ganymed</groupId>
  <artifactId>ganymed-ssh2</artifactId>
  <version>262</version>
</dependency>


上代码,封装的Util

public class SshShellUtil {

    private String hostName;

    private String userName;

    private String password;

    private String scriptEndWord;

    private String shCmd;

    public void runShell() throws IOException {
        Connection conn = null;
        Session sess = null;
        BufferedReader brs = null;

        log.info("準備鏈接");
        log.info("连接服务器 " + hostName + " ,执行shell:" + shCmd);

        try{
            conn = new Connection(hostName);
            conn.connect();

            boolean isAuthenticated = conn.authenticateWithPassword(userName, password);
            if (isAuthenticated == false)
                throw new IOException("Authentication failed.");
            sess = conn.openSession();
            sess.requestPTY("bash");
            sess.startShell();
            PrintWriter out = new PrintWriter(sess.getStdin());
            out.println(shCmd);
            out.flush();

            log.info("开始打印结果");
            InputStream stdout = new StreamGobbler(sess.getStdout());
            brs = new BufferedReader(new InputStreamReader(stdout));

            Thread.sleep(0);
            while(true){
                String line = brs.readLine();
                System.out.println(line);
//                Thread.sleep(200);
                if(null == line || scriptEndWord.equals(line)){
                    break;
                }
            }

            out.println("exit");
            out.close();
            sess.waitForCondition(ChannelCondition.CLOSED | ChannelCondition.EOF | ChannelCondition.EXIT_STATUS,
                    60000);

            log.info("結束");
        }
        catch (IOException | InterruptedException e){
            e.printStackTrace(System.err); System.exit(2);
        }finally{
            if(brs!=null)
                brs.close();
            //Close this session
            if(sess!=null)
                sess.close();
            // Close the connection
            if(conn!=null)
                conn.close();
        }
    }
}


调用代码

SshShellUtil sshShellUtil = new SshShellUtil();
sshShellUtil.setHostName(sshProDeployParam.getHostName());
sshShellUtil.setUserName(sshProDeployParam.getUserName());
sshShellUtil.setPassword(sshProDeployParam.getPassword());
sshShellUtil.setScriptEndWord("dep_scrip_done");
sshShellUtil.setShCmd("cd /data/dengwen_city_garden_api/ && sh script.sh");
ThreadUtil.execute(()->{
  try {
    shellUtil.runShell();
  } catch (IOException e) {
    e.printStackTrace();
  }
});


shCmd脚本,这里封装成为sh脚本。