远程连接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脚本。