import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import com.jcraft.jsch.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.Properties;
@Data
@Slf4j
@Component
public class ConnLinuxServerUtil {
/**
* 可以配置在nacos中 也可以通过参数传入
*/
// linux服务器IP地址
private String ip = "";
// linux登录用户名
private String uName = "";
// linux登录密码
private String uPwd = "";
// 字符编码
private static String DEFAULTCHART="UTF-8";
/**
* 需要导入的依赖
*
* <dependency>
* <groupId>ch.ethz.ganymed</groupId>
* <artifactId>ganymed-ssh2</artifactId>
* <version>build210</version>
* </dependency>
*/
private Connection connection;
private static ChannelSftp sftp = null;
/**
* 连接linux服务器方法
*
* @return
*/
public boolean connLinuxServer(){
boolean flag = false;
try {
// 创建连接对象
connection = new Connection(ip);
connection.connect();
// 验证用户名 密码
flag = connection.authenticateWithPassword(uName,uPwd);
} catch (IOException e) {
e.printStackTrace();
}
return flag;
}
/**
* 执行linux脚本
*
* @param cmd
* @return
*/
public String execute(String cmd){
String result="";
try {
// 如果登录成功的话
if(connLinuxServer()){
//打开一个会话
Session session= connection.openSession();
// 执行输入进来的命令 可以是linux命令 也可以是sh命令 执行sh脚本
session.execCommand(cmd);
result=processStdout(session.getStdout(),DEFAULTCHART);
//如果为得到标准输出为空,说明脚本执行出错了
if(StringUtils.isBlank(result)){
result=processStdout(session.getStderr(),DEFAULTCHART);
}
//关闭连接
connection.close();
// 关闭session对话
session.close();
}
} catch (Exception e) {
e.printStackTrace();
}
// 返回结果
return result;
}
/**
* 解析执行命令结果
*
* @param stdout
* @param defaultchart
* @return
*/
private String processStdout(InputStream stdout, String defaultchart) {
// 把session的标准输出包装成InputStream,用于接收目标服务器上的控制台返回结果,
// 读取br中的内容。然后在循环中,把每一行的内容添加到StringBuffer里面。
InputStream in = new StreamGobbler(stdout);
StringBuffer stringBuffer = new StringBuffer();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(in,defaultchart));
String line;
while((line = br.readLine()) != null){
stringBuffer.append(line+"\n");
}
} catch (Exception e) {
e.printStackTrace();
}
// 返回结果 形式为字符串
return stringBuffer.toString();
}
/**
* 将生成的文件传输到linux系统中(sh文件 )
*
* @param path
* @param filename
* @param input
* @return
*/
public boolean uploadFile(String path,String filename, InputStream input){
boolean flag = false;
FTPClient ftp = new FTPClient();
if(connLinuxServer()){
try {
JSch jsch = new JSch();
//获取sshSession 账号-ip-端口
com.jcraft.jsch.Session sshSession = jsch.getSession(uName, ip, 22);
sshSession.setPassword(uPwd);
Properties sshConfig = new Properties();
//严格主机密钥检查
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
//开启sshSession链接
sshSession.connect();
//获取sftp通道
Channel channel = sshSession.openChannel("sftp");
//开启
channel.connect();
sftp = (ChannelSftp) channel;
//服务器路径
/*file = new File("/home/tomcat/apache-tomcat-9.0.39/webapps/files/"+path);
file.mkdirs();*/
//设置为被动模式
ftp.enterLocalPassiveMode();
//验证是否存在目录,不存在的话创建
if(createDir(path,sftp)){
//设置上传文件的类型为二进制类型
//进入到要上传的目录 然后上传文件
sftp.cd(path);
sftp.put(input, filename);
}
input.close();
flag = true;
} catch (Exception e) {
e.printStackTrace();
}
}
return flag;
}
/**
* 创建目录
* @param createpath
* @return
*/
public static boolean createDir(String createpath, ChannelSftp sftp) {
try{
// 判断是否存在 如果存在直接进入
if (isDirExist(createpath,sftp)) {
sftp.cd(createpath);
return true;
}
String pathArry[] = createpath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
if (isDirExist(filePath.toString(),sftp)) {
sftp.cd(filePath.toString());
} else {
// 建立目录
sftp.mkdir(filePath.toString());
// 进入并设置为当前目录
sftp.cd(filePath.toString());
}
}
sftp.cd(createpath);
return true;
}
catch (SftpException e) {
e.printStackTrace();
}
return false;
}
/**
* 判断目录是否存在
* @param directory
* @return
*/
public static boolean isDirExist(String directory, ChannelSftp sftp){
boolean isDirExistFlag = false;
try{
// 检索文件或者目录的属性
SftpATTRS sftpATTRS = sftp.lstat(directory);
isDirExistFlag = true;
// 检查文件是否为目录
return sftpATTRS.isDir();
}
catch (Exception e){
if (e.getMessage().toLowerCase().equals("no such file")){
isDirExistFlag = false;
}
}
return isDirExistFlag;
}
}
测试:
import com.example.jenkinsjavaapidemo.util.ConnLinuxServerUtil;
import com.example.jenkinsjavaapidemo.util.CreateShellFileUtil;
import org.springframework.stereotype.Service;
@Service
public class LinuxOperateService {
CreateShellFileUtil createShellFileUtil = new CreateShellFileUtil();
ConnLinuxServerUtil connLinuxServerUtil = new ConnLinuxServerUtil();
/**
* 创建shell文件 并输出内容
*
*/
public void createShellFile(){
String resString = "";
try {
// File shellFile = createShellFileUtil.createShellFile("test.sh",new ArrayList<>());
// 读取生成后的shell文件内容
// resString = FileUtils.readFileToString(new File("test.sh"), StandardCharsets.UTF_8);
// 连接linux服务器
connLinuxServerUtil.connLinuxServer();
// InputStream in =new FileInputStream(shellFile);
// 上传文件至服务器的指定目录
// connLinuxServerUtil.uploadFile("/usr/local/shtest","test.sh",in);
// connLinuxServerUtil.execute("chmod -R 755 /usr/local/shtest/test.sh");
// connLinuxServerUtil.execute("sed -i 's/\\r$//' /usr/local/shtest/test.sh");
String execute = connLinuxServerUtil.execute("sh /usr/local/shtest/test.sh");
System.out.println(execute);
} catch (Exception e) {
e.printStackTrace();
}
}
}