资讯专栏INFORMATION COLUMN

基于Jsch实现Java操作linux服务器

IT那活儿 / 519人阅读
基于Jsch实现Java操作linux服务器

点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!!


文章前言

如果大家熟悉Linux的话,一定对ssh,sftp,scp等命令非常熟悉。ssh是一个安全协议,用来在不同系统或者服务器之间进行安全连接。ssh在连接和传送的过程中会加密所有的数据。
但是ssh一般是基于客户端的或者Linux命令行的。比如客户端工具:OpenSSH,putty,SSHTectia。
在linux系统上大家可以通过sshusername@host命令连接到目标主机,但是如果在Java中,如何实现SSH功能呢更进一步如何实现SCP,SFTP的功能呢

目前Java主流操作linux服务器基本都是基于Jschganymed-ssh2Jschganymed-ssh2都是用纯Java实现SSH-2协议的一个包。两者大同小异,下面笔者重点讲解下如何在Java代码中基于Jsch连接并操作linux系统。


实际应用

目前在湖南客户现场的日志分析项目中,我们正是基于jsch实现java操作linux服务器,实现脚本库的功能。
2.1 Pom文件中配置相应的jsch的jar包

<dependency>
<groupId>com.jcraftgroupId>
<artifactId>jschartifactId>
<version>0.1.54version>
dependency>
2.2 建立一个SSH会话
publicstatic Session openSession(String sshHost, int sshPort, StringsshUser, String sshPass)
throwsDeployException
{
finalJSch jsch = new JSch();
Sessionsession;
try{
session= jsch.getSession(sshUser, sshHost, sshPort);
}catch (JSchException e) {
logger.error(sshHost,e);
thrownew DeployException("创建一个新的session异常");
}
//设置第一次登录的时候提示,可选值:(ask| yes | no)
session.setConfig("StrictHostKeyChecking","no");
session.setPassword(sshPass);
try{
session.connect();
}catch (JSchException e) {
logger.error("openSession异常",e);
thrownew DeployException("创建一个新的session异常");
}
returnsession;
}
2.3 执行Shell命令
publicstatic String execCommand(Session session, String cmd, Charsetcharset, long timeout)
throwsDeployException, TimeOutException
{
StringBufferresult = new StringBuffer();
ChannelExecexec = null;
try{
exec= (ChannelExec)createChannel(session, ChannelType.EXEC);
cmd= cmd + " 2>&1";
exec.setCommand(cmd);
exec.setInputStream(null);
logger.info(newStringBuilder(exec.getSession().getHost()).append(",执行输出命令:").append(cmd).toString());
try(InputStream stdout = exec.getInputStream()) {
exec.connect();
longstartTime = System.currentTimeMillis();
byte[]tmp = new byte[1024];
while(true) {
while(stdout.available() > 0) {
inti = stdout.read(tmp, 0, 1024);
if(i < 0)
break;
result.append(newString(tmp, 0, i, Charset.defaultCharset()));
}
if(exec.isClosed()) {
if(stdout.available() > 0)
continue;
break;
}
//超时
if(System.currentTimeMillis() - startTime > timeout) {
thrownew TimeOutException("sh命令执行超时:"+ cmd);
}
}
}
}catch (TimeOutException t) {
throwt;
}catch (Exception e) {
//result.append(e.getMessage());
logger.error("execCommand异常",e);
thrownew DeployException("ssh 异常",e);
}finally {
close(exec);
}
if(result.length() > 0)
result.deleteCharAt(result.length()- 1);
returnresult.toString();
}
测试执行shell命令:
运行结果:
这样就和在原linux系统中一样使用shell功能了。
2.4 创建sftp通道
publicstatic Channel openChannel(Session session, ChannelType channelType)throws DeployException {
Channelchannel;
try{
if(false == session.isConnected()) {
session.connect();
}
channel= session.openChannel(ChannelType.SFTP.getValue());
}catch (JSchException e) {
logger.error(session.getHost(),e);
thrownew DeployException("创建一个新的Channel异常");
}
try{
channel.connect();
}catch (JSchException e) {
logger.error(session.getHost(),e);
thrownew DeployException("创建一个新的Channel异常");
}
return(ChannelSftp)channel;
}

ChannelSftp类是JSch实现SFTP核心类,它包含了所有SFTP的方法,如:

  • put():    文件上传
  • get():    文件下载
  • cd():     进入指定目录
  • ls():     得到指定目录下的文件列表
  • rename(): 重命名指定文件或目录
  • rm():     删除指定文件
  • mkdir():  创建目录
  • rmdir():  删除目录

...等等(这里省略了方法的参数,put和get都有多个重载方法,大家如需使用请看具体源代码,这里篇幅有限就不一一列出。)

注意事项:
JSch是以多线程方式连接,所以程序在connect后如果不disconnectchannel和session以及相关stream,进程会一直等待,开发同事在编写代码时切记在使用完毕,须在最后finally中disconnect掉所有连接通道。

使用总结

我们再次回顾总结下使用Jsch步骤:

  • new一个JSch对象;
  • 从JSch对象中获取Session,用于连接,并设置连接信息;
  • 使用session对象调用opnChannel("xxx")打开通信信道,并连接;
  • 后面就是不同的channel,不同的操作(常用的有三种通道,即ChannelShell、ChannelExec、ChannelSftp,前两类用于执行命令,后一种是用于上传下载文件)在实际项目中,我们可以基于jsch实现java操作linux服务器执行相应的命令,或者上传下发删除文件以及远程调用脚本,最终达到实现项目自动化运维的这个小目标。


文章首发于2020年10月1日.




本文作者:邓 鑫(上海新炬王翦团队)

本文来源:“IT那活儿”公众号

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/129260.html

相关文章

  • JSch-用java实现务器远程操作

    摘要:主要是将一个服务集群部署到远端的服务器上,具体服务器的连接信息会通过接口传入。本来部署是人工来完成的,无非是将一些必须的文件到目标服务器上,然后远程登录,执行一些安装的操作,齐活。 介绍 前段时间接了一个比较特殊的需求,需要做一个用于部署服务的服务。主要是将一个k8s服务集群部署到远端的服务器上,具体服务器的连接信息会通过接口传入。 本来部署是人工来完成的,无非是将一些必须的文件s...

    孙吉亮 评论0 收藏0
  • Docker技术三大要点:cgroup, namespace和unionFS的理解

    摘要:而是基于容器的这个设计思想,基于技术实现的核心管理引擎。的三大特色,和。不同内的进程属于不同的,彼此透明,互不干扰。看下面的图加深理解。同样内核版本的不同的发行版,其都是一致的。 www.docker.com的网页有这样一张有意思的动画: showImg(https://segmentfault.com/img/remote/1460000017474530); 从这张gif图片,我们...

    Zachary 评论0 收藏0
  • 技术选型之Docker容器引擎

    摘要:是系统提供的容器化技术,简称,它结合和技术为用户提供了更易用的接口来实现容器化。公司结合和以下列出的技术实现了容器引擎,相比于,具备更加全面的资源控制能力,是一种应用级别的容器引擎。 showImg(https://segmentfault.com/img/bVbtPbG?w=749&h=192); 题外话   最近对Docker和Kubernetes进行了一番学习,前两天做了一次技术...

    monw3c 评论0 收藏0

发表评论

0条评论

IT那活儿

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<