项目中经常会遇到在代码中实现执行shell命令的需求,或者通过ftp传输文件的需求。分为两种情况:
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.27</version>
</dependency>
/**
* 登陆并打开服务器会话
* @param ip 目标主机名或ip
*/
private static Session getSession(String ip, String username, String password, Integer port) {
Session session = null;
JSch jSch = new JSch();
try {
if (port != null) {
session = jSch.getSession(username, ip, port.intValue());
} else {
session = jSch.getSession(username, ip);
}
if (password != null) {
session.setPassword(password);
}
//关闭主机密钥检查,否则会导致连接失败
Properties properties = new Properties();
properties.setProperty("StrictHostKeyChecking", "no");
session.setConfig(properties);
//打开会话,并设置超时时间
session.connect(30000);
} catch (JSchException e) {
e.printStackTrace();
}
return session;
}
/**
* 获取sftp连接
*/
public static ChannelSftp getChannelSftp(Session session) {
ChannelSftp channel = null;
try {
//打开通道,设置通道类型
channel = (ChannelSftp) session.openChannel("sftp");
channel.connect();
} catch (Exception e) {
e.printStackTrace();
}
return channel;
}
/**
* 示例四:向指定服务器的路径上传文件
* @param ip
* @param username
* @param password
* @param port
* @param srcPath 本地文件路径
* @param desPath 服务器目标路径(带文件名)
* @return
*/
public static Boolean upload(String ip, String username, String password, Integer port,String srcPath,String desPath) {
Boolean flage = false;
Session session = getSession(ip, username, password, port);
ChannelSftp channelSftp = getChannelSftp(session);
try {
InputStream inputStream = new FileInputStream(srcPath);
//上传
channelSftp.put(inputStream,desPath);
channelSftp.quit();
channelSftp.exit();
flage = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
channelSftp.disconnect();
session.disconnect();
}
return flage;
}
// 测试
public static void main(String[] args) {
Boolean b = upload("192.168.136.101", "hdp", "111111", 22,"D:\\feiq\\FeiqCfg.xml","/home/hdp/manage/FeiqCfg.xml");
if (b) System.out.println("上传成功");
}
/**
* 打开exec通道
*/
public static ChannelExec getChannelExec(Session session) {
ChannelExec channel = null;
try {
//设置通道类型
channel = (ChannelExec) session.openChannel("exec");
} catch (Exception e) {
e.printStackTrace();
}
return channel;
}
/**
* 示例三:直接获取服务器磁盘使用情况(不读写文件的方式)
*/
public static List<String[]> getDiskUsage(String ip, String username, String password, Integer port) {
List<String[]> result = null;
Session session = getSession(ip, username, password, port);
ChannelExec channelExec = getChannelExec(session);
try {
channelExec.setCommand("df -hl | awk '{if (NR>1){print}}'");
channelExec.connect();
InputStream inputStream = channelExec.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while ((line = reader.readLine()) != null) {
String[] split = line.split("\\s+");
result.add(split);
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
channelExec.disconnect();
session.disconnect();
}
return result;
}
// 测试
public static void main(String[] args) {
List<String[]> usage = getDiskUsage("192.168.136.101", "hdp", "111111", 22);
usage.forEach(x -> System.out.println(x));
//Boolean b = upload("192.168.136.101", "hdp", "111111", 22,"D:\\feiq\\FeiqCfg.xml","/home/manage/FeiqCfg.xml");
//if (b) System.out.println("上传成功");
}
注意
1.登陆服务器是,支持密钥的方式登陆,只需在jsch.getSession之前调用jsch.addIdentity方法设置一下密钥的相关信息就可以了
2.通道断开后,还要将session断开,否则程序将一直处于运行状态