基于Jsch实现Java操作linux服务器
作为熟悉Linux的程序员,大家一定对ssh、sftp、scp等命令非常熟悉。ssh是一个安全协议,用来在不同的系统或者服务器之间进行安全连接。但是ssh一般是基于客户端的或者Linux命令行的,那么在Java中如何实现SSH、SCP、SFTP功能呢?目前Java主流操作linux服务器基本都是基于Jsch与ganymed-ssh2。Jsch与ganymed-ssh2都是用纯Java实现SSH-2协议的一个包。以下为操作步骤。

实际应用
目前在湖南移动的日志分析项目中,我们正是基于Jsch实现java操作linux服务器,实现脚本库的功能。
1、Pom文件中配置相应的jsch的jar包com.jcraft.jsch0.1.54;
2、建立一个SSH会话
public static Session openSession(String sshHost, int sshPort, String sshUser, String sshPass) throws DeployException {
final JSch jsch = new JSch();
Session session;
try {
session = jsch.getSession(sshUser, sshHost, sshPort);
} catch (JSchException e) {
logger.error(sshHost, e);
throw new DeployException(“创建一个新的session异常”);
}
//设置第一次登录的时候提示,可选值:(ask|yes|no)
session.setConfig(“StrictHostKeyChecking”, “no”);
session.setPassword(sshPass);
try {
session.connect();
} catch (JSchException e) {
logger.error(“openSession异常”, e);
throw new DeployException(“创建一个新的session异常”);
}
return session;
}
3、执行Shell命令
public static String execCommand(Session session, String cmd, Charset charset, long timeout) throws DeployException, TimeOutException {
StringBuffer result = new StringBuffer();
ChannelExec exec = null;
try {
exec = (ChannelExec) createChannel(session, ChannelType.EXEC);
cmd = cmd + ” 2>&1″;
exec.setCommand(cmd);
exec.setInputStream(null);
logger.info(new StringBuilder(exec.getSession().getHost()).append(“,执行输出命令:”).append(cmd).toString());
try (InputStream stdout = exec.getInputStream()) {
exec.connect();
long startTime = System.currentTimeMillis();
byte[] tmp = new byte[1024];
while (true) {
while (stdout.available() > 0) {
int i = stdout.read(tmp, 0, 1024);
if (i < 0) break;
result.append(new String(tmp, 0, i, Charset.defaultCharset()));
}
if (exec.isClosed()) {
if (stdout.available() > 0) continue;
break;
}
//超时
if (System.currentTimeMillis() – startTime > timeout) {
throw new TimeOutException(“sh命令执行超时:” + cmd);
}
}
}
} catch (TimeOutException t) {
throw t;
} catch (Exception e) {
logger.error(“execCommand异常”, e);
throw new DeployException(“ssh异常”, e);
} finally {
close(exec);
}
if (result.length() > 0) result.deleteCharAt(result.length() – 1);
return result.toString();
}
4、创建sftp通道
public static Channel openChannel(Session session, ChannelType channelType) throws DeployException {
Channel channel;
try {
if (false == session.isConnected()) {
session.connect();
}
channel = session.openChannel(ChannelType.SFTP.getValue());
} catch (JSchException e) {
logger.error(session.getHost(), e);
throw new DeployException(“创建一个新的Channel异常”);
}
try {
channel.connect();
} catch (JSchException e) {
logger.error(session.getHost(), e);
throw new DeployException(“创建一个新的Channel异常”);
}
return (ChannelSftp) channel;
}
ChannelSftp类是JSch实现SFTP核心类,它包含了所有SFTP的方法,如:put():文件上传、get():文件下载、cd():进入指定目录、ls():得到指定目录下的文件列表、rename():重命名指定文件或目录、rm():删除指定文件、mkdir():创建目录、rmdir():删除目录等等。
注意事项
JSch是以多线程方式连接,所以程序在connect后如果不disconnect channel和session以及相关stream,进程会一直等待,因此在编写代码时切记在使用完毕后,在最后finally中disconnect掉所有连接通道。
使用总结
在实际项目中,我们可以基于Jsch实现Java操作linux服务器执行相应的命令,或者上传下发删除文件以及远程调用脚本,最终达到实现项目自动化运维的这个小目标。
操作步骤总结如下:
- new一个JSch对象;
- 从JSch对象中获取Session,用于连接,并设置连接信息;
- 使用session对象调用opnChannel(“xxx”)打开通信信道,并连接;
- 后面就是不同的channel,不同的操作(常用的有三种通道,即ChannelShell、ChannelExec、ChannelSftp,前两类用于执行命令,后一种是用于上传下载文件)。
原创文章,作者:小编小本本,如若转载,请注明出处:https://www.benjiyun.com/yunzhujiyunwei/vps-yunwei/5843.html
