其实各种博客各种工具类非常多,但是都不够全面。
这里呢,主要实现的功能就是我本地自己创建一个test.sh的脚本,
内容就是:echo "hello word!";
通过java把脚本上传到linux服务器上,并授予权限,执行此脚本,并且把脚本的执行结果返回,打印到控制台。
话不多说直接上代码:
1.先引入依赖:
ch.ethz.ganymed
ganymed-ssh2
build210
org.apache.directory.studio
org.apache.commons.lang
2.6
com.jcraft
jsch
0.1.54
2.创建相关执行类
public class Script {
//字符编码默认是utf-8
private static String DEFAULTCHART="UTF-8";
private Connection conn;
private String ip;
private String userName;
private String userPwd;
public Script(String ip, String userName, String userPwd) {
this.ip = ip;
this.userName = userName;
this.userPwd = userPwd;
}
public Boolean login(){
boolean flg=false;
try {
conn = new Connection(ip);
conn.connect();//连接
flg=conn.authenticateWithPassword(userName, userPwd);//认证
} catch (IOException e) {
e.printStackTrace();
}
return flg;
}
/**
* 远程执行shll脚本或者命令
* @param cmd 即将执行的命令
* @return 命令执行完后返回的结果值
* @since V0.1
*/
public String execute(String cmd){
String result="";
try {
if(login()){
Session session= conn.openSession();//打开一个会话
session.execCommand(cmd);//执行命令
result=processStdout(session.getStdout(),DEFAULTCHART);
//如果为得到标准输出为空,说明脚本执行出错了
if(StringUtils.isBlank(result)){
result=processStdout(session.getStderr(),DEFAULTCHART);
}
conn.close();
session.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 远程执行shll脚本或者命令
* @param cmd 即将执行的命令
* @return 命令执行成功后返回的结果值,如果命令执行失败,返回空字符串,不是null
*/
public String executeSuccess(String cmd){
String result="";
try {
if(login()){
Session session= conn.openSession();//打开一个会话
session.execCommand(cmd);//执行命令
result=processStdout(session.getStdout(),DEFAULTCHART);
conn.close();
session.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 解析脚本执行返回的结果集
* @author Ickes
* @param in 输入流对象
* @param charset 编码
* @return 以纯文本的格式返回
*/
private String processStdout(InputStream in, String charset){
InputStream stdout = new StreamGobbler(in);
StringBuffer buffer = new StringBuffer();;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(stdout,charset));
String line=null;
while((line=br.readLine()) != null){
buffer.append(line+"\n");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return buffer.toString();
}
public static void setCharset(String charset) {
DEFAULTCHART = charset;
}
public Connection getConn() {
return conn;
}
public void setConn(Connection conn) {
this.conn = conn;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
/*public static void main(String[] args) {
Script rec=new Script("172.16.204.158", "root","123qwe!@#");
//执行命令
System.out.println(rec.execute("/home/test.sh"));
}*/
}
3.实现接口
/**
* @ClassName ScriptUploadService
* @Author MCP
* @Description 脚本上传执行相关接口
* @Date 2021/3/8 11:15
* Version 1.0
**/
public interface ScriptService {
void createChannel(SftpAuthority sftpAuthority);
void closeChannel();
boolean uploadFile(SftpAuthority sftpAuthority, String src, String dst);
boolean removeFile(SftpAuthority sftpAuthority, String dst);
}
4.接口的实现类
/**
* @ClassName ScriptUploadServiceImpl
* @Author MCP
* @Description 脚本上传执行相关接口
* @Date 2021/3/8 11:17
* Version 1.0
**/
@Service
public class ScriptServiceImpl implements ScriptService {
private Session session;
private Channel channel;
private ChannelSftp channelSftp;
//建立通道
@Override
public void createChannel(SftpAuthority sftpAuthority) {
try {
JSch jSch = new JSch();
session = jSch.getSession(sftpAuthority.getUser(), sftpAuthority.getHost(), sftpAuthority.getPort());
if (sftpAuthority.getPassword() != null) {
// 使用用户名密码创建SSH
session.setPassword(sftpAuthority.getPassword());
} else if (sftpAuthority.getPrivateKey() != null) {
// 使用公私钥创建SSH
jSch.addIdentity(sftpAuthority.getPrivateKey(), sftpAuthority.getPassphrase());
}
Properties properties = new Properties();
properties.put("StrictHostKeyChecking", "no"); // 主动接收ECDSA key fingerprint,不进行HostKeyChecking
session.setConfig(properties);
session.setTimeout(0); // 设置超时时间为无穷大
session.connect(); // 通过session建立连接
channel = session.openChannel("sftp"); // 打开SFTP通道
channel.connect();
channelSftp = (ChannelSftp) channel;
} catch (JSchException e) {
e.printStackTrace();
}
}
@Override
public void closeChannel() {
if (channel != null) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
//上传文件
@Override
public boolean uploadFile(SftpAuthority sftpAuthority, String src, String dst) {
if (channelSftp == null) {
System.out.println("need create channelSftp before upload file");
return false;
}
if (channelSftp.isClosed()) {
createChannel(sftpAuthority); // 如果被关闭则应重新创建
}
try {
channelSftp.put(src, dst, ChannelSftp.OVERWRITE);
System.out.println("sftp upload file success! src: {}, dst: {}"+src+"---"+dst);
return true;
} catch (SftpException e) {
System.out.println("sftp upload file failed!");
return false;
}
}
//移除文件
@Override
public boolean removeFile(SftpAuthority sftpAuthority, String dst) {
if (channelSftp == null) {
return false;
}
if (channelSftp.isClosed()) {
createChannel(sftpAuthority); // 如果被关闭则应重新创建
}
try {
channelSftp.rm(dst);
return true;
} catch (SftpException e) {
return false;
}
}
}
5.搞个接口测试一下:具体调用如下:
@Autowired
private ScriptService scriptService;
/***
* @Author MCP
* @Description 根据deployment查询对应的yaml
* @Date 10:26 2021/2/24
* @Param
* @return
**/
@GetMapping("/test")
public void test(){
// 主机/ip
String hostname="172.16.XXX.XXX";
//用户名
String username="root";
//端口
int port=22;
//密码
String password="XXXXXXX";
//授权的命令
String command="chmod 777 /home/test02.sh";
//文件所在本地的路径
String sourceDir="C:/Users/machunpeng/Desktop/test.sh";
//上传后的路径
String dstDir="/home/test02.sh";
// 用户名密码方式
// ScriptService sftpService = context.getBean(ScriptService.class);
SftpAuthority sftpAuthority = new SftpAuthority(username, hostname, 22);
sftpAuthority.setPassword(password);
scriptService.createChannel(sftpAuthority);
/*****此处的dstDir是上传到服务器的地址:
可以是"/home",那么上传后的文件和原文件名一直
可以是"/home/test02.sh",那么上传后的文件由test.sh改名为test02.sh ****/
scriptService.uploadFile(sftpAuthority, sourceDir, dstDir);
// sftpService.removeFile(sftpAuthority, "/user/testaaa.png"); 移除
//修改文件权限
Script rec=new Script(hostname, username,password);
rec.execute(command);
//执行脚本
System.out.println(rec.execute(dstDir));
scriptService.closeChannel();
// 公私钥方式
/* sftpAuthority = new SftpAuthority("user", "ip or host", port);
sftpAuthority.setPrivateKey("your private key full path");
sftpAuthority.setPassphrase("private key passphrase");
scriptService.createChannel(sftpAuthority);
scriptService.uploadFile(sftpAuthority, "/home/snow/test/test.png", "/user/testaaa.png");
scriptService.removeFile(sftpAuthority, "/user/testaaa.png");
scriptService.closeChannel();*/
}
至此就全部完成啦。