在工作中,比如我们的产品是需要根据代码中的情况,时时的去操作远程的服务器, 所以这样不能通过固定的shell脚本去完成,所以就只能在java中通过shell命令远程的操作服务器。所以本博客就是,在java中,通过使用shell命令操作远程的服务器。 本类包含: 远程执行shell命令, 文件上传下载,文件删除,查询文件列表几个方法。 话不多说,直接上代码:
因为这个是使用的jsch工具,所以需要首先导入这个包, maven下引入:
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
非maven项目的话,可以通点击后面下载jar包:点击下载
,没有积分的可以后面留言,我发送到邮箱
package com.bdm.pojo;
import java.io.Serializable;
/**
*@Packge: com.bdm.pojo
*@Description: 远程连接服务器并发送命令的登陆信息
*@author: mulming
*@data: Dec 25, 2019 10:54:04 AM
*/
public class SSHLoginInfo implements Serializable{
/**
*@Packge: com.bdm.pojo
*@author: mulming
*@data: Dec 25, 2019 11:16:30 AM
*/
private static final long serialVersionUID = 1L;
private String ipAddress;// ip 地址
private String userName;// 登陆帐号
private String passWord;// 登陆密码
public String getIpAddress() {
return ipAddress;
}
public String getUserName() {
return userName;
}
public String getPassWord() {
return passWord;
}
public static class Builder{
private String ipAddress;// ip 地址
private String userName;// 登陆帐号
private String passWord;// 登陆密码
public Builder setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
return this;
}
public Builder setUserName(String userName) {
this.userName = userName;
return this;
}
public Builder setPassWord(String passWord) {
this.passWord = passWord;
return this;
}
public SSHLoginInfo build() {
return new SSHLoginInfo(this);
}
}
private SSHLoginInfo(Builder builder) {
this.ipAddress = builder.ipAddress;
this.userName = builder.userName;
this.passWord = builder.passWord;
}
}
package com.bdm.ssh.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import java.util.Vector;
import org.apache.log4j.Logger;
import com.bdm.common.tools.DBCommonTools;
import com.bdm.pojo.SSHLoginInfo;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
/**
*@Packge: com.shell
*@Description: exec用于执行命令;sftp用于文件处理
*@author: mulming
*@data: Dec 23, 2019 9:03:41 PM
*/
public class SSHRemoteUtil {
public static Logger LOG = Logger.getLogger(SSHRemoteUtil.class);
private static volatile SSHRemoteUtil instance = null;
private static final int DEFAULT_PORT = 22;// 默认端口号
private Session session;// JSCH session
private boolean logined = false;// 是否登陆
private SSHRemoteUtil() {}
public static SSHRemoteUtil getInstance() {
if(instance == null) {
synchronized (DBCommonTools.class) {
if(instance == null) {
instance = new SSHRemoteUtil();
}
}
}
return instance;
}
/**
*@Description: 远程登陆
*@author: mulming
*@param: @param ipAddress ip
*@param: @param userName 帐号
*@param: @param password 密码
*@param: @throws Exception
*@return: void
*/
public void sshRemoteCallLogin(SSHLoginInfo loginInfo) {
// 如果登陆就直接返回
if (logined) {
return;
}
// 创建jSch对象
JSch jSch = new JSch();
try {
// 获取到jSch的session, 根据用户名、主机ip、端口号获取一个Session对象
session = jSch.getSession(loginInfo.getUserName(), loginInfo.getIpAddress(), DEFAULT_PORT);
// 设置密码
session.setPassword(loginInfo.getPassWord());
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
// session.setTimeout(3000);// 设置超时
session.connect(); 通过Session建立连接
// 设置登陆状态
logined = true;
LOG.info("SSH connection success ...");
} catch (JSchException e) {
// 设置登陆状态为false
logined = false;
LOG.info("主机登录失败, IP = " + loginInfo.getIpAddress() + ", USERNAME = " + loginInfo.getUserName() + ", Exception:" + e);
}
}
/**
* 关闭连接
*/
public void closeSession() {
// 调用session的关闭连接的方法
if (session != null) {
// 如果session不为空,调用session的关闭连接的方法
session.disconnect();
}
LOG.info("SSH close success ...");
}
/**
*@Description: 执行相关的命令
*@author: mulming
*@param: @param command 具体的命令
*@param: @throws IOException
*@return: String : 返回命令执行后的结果
*/
public String execCommand(String command){
InputStream in = null;// 输入流(读)
Channel channel = null;// 定义channel变量
try {
// 如果命令command不等于null
if (command != null) {
// 打开channel
//说明:exec用于执行命令;sftp用于文件处理
channel = session.openChannel("exec");
// 设置command
((ChannelExec) channel).setCommand(command);
// channel进行连接
channel.connect();
// 获取到输入流
in = channel.getInputStream();
// 执行相关的命令
String processDataStream = processDataStream(in);
return processDataStream;
}
} catch (JSchException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
LOG.error(e);
e.printStackTrace();
}
}
if (channel != null) {
channel.disconnect();
}
}
return null;
}
/**
*@Description:内部使用 对将要执行的linux的命令进行遍历,专门处理执行,以及执行后返回的命令
*@author: mulming
*@param: @param in
*@param: @return
*@param: @throws Exception
*@return: String
*/
private String processDataStream(InputStream in){
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String result = "";
try {
while ((result = br.readLine()) != null) {
sb.append(result + "\n");
}
} catch (Exception e) {
LOG.error("Failed to get BufferedReader: ",e);
} finally {
if(br != null) {
try {
br.close();
} catch (IOException e) {
LOG.error(e);
}
}
}
return sb.toString();
}
/**
*@Description: 上传文件 可参考:https://www.cnblogs.com/longyg/archive/2012/06/25/2556576.html
*@author: mulming
*@param: @param directory 上传文件的目录,即服务端的目录
*@param: @param uploadFile 将要上传的文件,本地文件
*@return: void
*/
public void uploadFile(String directory, String uploadFile) {
try {
System.out.println(" Upload start .....");
// 打开channelSftp
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect();
// 创建一个文件名称问uploadFile的文件
File file = new File(uploadFile);
// 将文件进行上传(sftp协议)
// 将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同.
// 采用默认的传输模式:OVERWRITE
channelSftp.put(new FileInputStream(file), directory, ChannelSftp.OVERWRITE);
// 切断远程连接
channelSftp.exit();
System.out.println( file.getName() + " Upload success .....");
} catch (JSchException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/**
*@Description: TODO下载文件 采用默认的传输模式:OVERWRITE
*@author: mulming
*@param: @param src linux服务器文件地址
*@param: @param dst 本地存放地址
*@return: void
*/
public void fileDownload(String src, String dst){
try {
// src 是linux服务器文件地址,dst 本地存放地址
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect();
// 下载文件,多个重载方法
channelSftp.get(src, dst);
// 切断远程连接,quit()等同于exit(),底层 disconnect();
channelSftp.quit();
} catch (JSchException e) {
LOG.error(e);
e.printStackTrace();
} catch (SftpException e) {
LOG.error(e);
e.printStackTrace();
}
LOG.info(src + " ,download complete.....");
}
/**
*@Description: 删除文件
*@author: mulming
*@param: @param directoryFile 要删除文件所在目录
*@return: void
*/
public void deleteFile(String directoryFile) throws SftpException, JSchException {
// 打开openChannel的sftp
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect();
// 删除文件
channelSftp.rm(directoryFile);
// 切断远程连接
channelSftp.exit();
LOG.info(directoryFile + " delete complete.....");
}
/**
*@Description: 列出目录下的文件
*@author: mulming
*@param: @param directory 要列出的目录
*@param: @throws JSchException
*@param: @throws SftpException
*@return: Vector
*/
public Vector<LsEntry> listFiles(String directory) throws JSchException, SftpException {
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
// 远程连接
channelSftp.connect();
// 显示目录信息
@SuppressWarnings("unchecked")
Vector<LsEntry> ls = channelSftp.ls(directory);
// 切断连接
channelSftp.exit();
return ls;
}
}
package com.shell;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Vector;
import org.junit.After;
import org.junit.Test;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.bdm.pojo.SSHLoginInfo;
import com.bdm.ssh.util.SSHRemoteUtil;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;
public class TestOracleEXP {
static {
//int port;// 端口号
String ipAddress = "xxx";// ip地址
String userName = "xxx";// 账号
String password = "xxx";// 密码
try {
// 首先远程连接ssh
SSHLoginInfo info=new SSHLoginInfo.Builder().setIpAddress(ipAddress).setUserName(userName).setPassWord(password).build();
SSHRemoteUtil.getInstance().sshRemoteCallLogin(info);
} catch (Exception e) {
e.printStackTrace();
}
}
@After // 7、关闭连接
public void CloseConn() {
System.out.println("close conn ...");
SSHRemoteUtil.getInstance().closeSession();
}
@Test //测试执行命令
public void TestExecCommand() throws IOException {
String command = "ls /opt ";
String string = SSHRemoteUtil.getInstance().execCommand(command);
System.out.println(string);
}
@Test // 测试上传文件
public void TestUploadFile() {
String directory = "/home/bdm/mlm1.text";// 目标文件名
String uploadFile = "/home/marico/mlm.test";// 本地文件名
SSHRemoteUtil.getInstance().uploadFile(directory, uploadFile);
}
@Test //测试下载文件
public void TestFileDownLoad() throws JSchException, SftpException {
String src = "/home/bdm/mlm1.text";
String dst = "/home/marico";
SSHRemoteUtil.getInstance().fileDownload(src, dst);
}
@Test
public void TestDeleteFile() throws SftpException, JSchException {
SSHRemoteUtil.getInstance().deleteFile("/home/bdm/mlm.txt");
}
@Test
public void TestListFiles() throws JSchException, SftpException {
Vector<LsEntry> listFiles = SSHRemoteUtil.getInstance().listFiles("/home/bdm");
for(LsEntry s:listFiles) {
//System.out.println(s.getLongname());
// System.out.println(s.getFilename());
System.out.println(s.getClass());
}
}
}