使用过ACS(Auto-ConfigurationServer -自动配置服务器)组件的同学都知道其核心功能是通过通过Java程序连接Linux服务器执行Shell命令、上传文件等。而通过Java程序连接Linux服务器的核心组件就是JSch(Java Secure Channel)。
JSch 是SSH2(SSH是一个安全协议,用来在不同系统或者服务器之间进行安全连接)的一个纯Java实现。它允许你连接到一个SSHD服务器,使用端口转发,X11转发进行Shell命令发送及执行,同时还可以sftp方式进行文件传输。我们可以将它的功能集成到Java程序中,从而使Java程序可以连接Linux服务器。另外该项目也提供一个J2ME版本用来在手机上直连SSHD服务器。
JSch官方地址为:http://www.jcraft.com/jsch/
GitHub 地址为:https://github.com/vngx/vngx-jsch
Java程序引入JSch组件只要通过Maven方式引入依赖:

<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
 
JSch基础知识
JSch常用的有三种通道:ChannelShell、ChannelExec、ChannelSftp;ChannelShell和ChannelExec都用于执行命令,ChannelSftp用于上传下载文件。
1、ChannelShell和ChannelExec的区别
ChannelShell是交互式的,需要获取输出流和输入流,使用输出流发送命令,从输入流中读取命令执行的结果;
ChannelExec是非交互的,其返回的信息非常干净,只返回标准输出;
ChannelShell和ChannelExec均是输入一个字符串命令(command)进行执行,这个字符串可以包含一条或者多条shell命令,命令之间分割符不同决定了不同的返回结果:
1) 每个命令之间用”;“隔开
各命令的执行结果,不会影响其它命令的执行,也就是说各个命令都会执行,但不保证每个命令都执行成功;
2) 每个命令之间用”&&“隔开
&&是并且的意思,只有前面的命令执行成功,才会去执行后面的命令;
3) 每个命令之间用”||”隔开
||是或的意思,只有前面的命令执行失败后才去执行下一条命令,直到执行成功一条命令为止。
JSch的使用步骤
1、new一个JSch对象;

JSch jsch = new JSch();
 
2、从JSch对象中获取Session,用于连接,并设置连接信息

Session session = jsch.getSession(name, ip, port);
session.setPassword(password);
Properties config = new Properties();
config.put(“StrictHostKeyChecking”, “no”);
session.setConfig(config);
session.setTimeout(30000);
session.connect();
 
对于连接Linux有时有弹出检测提示,如下所示:

The authenticity of host ‘10.10.64.242’ can’t be established.
RSA key fingerprint is 59:0f:32:fc:7b:54:3d:90:c0:ef:5a:6b:fb:11:55:e1.
Are you sure you want to continue connecting?
 
为了跳过这个提示可以,在Session连接配置中加入配置:

Properties config = new Properties();
config.put(“StrictHostKeyChecking”, “no”);
session.setConfig(config);
 
3、使用session对象调用openChannel(“xxx”)打开通信信道,并连接;

ChannelExec channel = (ChannelExec)session.openChannel(“exec”);
ChannelShell channel = (ChannelShell)session.openChannel(“shell”);
ChannelSftp channel = (ChannelSftp)session.openChannel(“sftp”);
 
4、针对不同的channel(ChannelShell、ChannelExec、ChannelSftp)执行不同的操作

ChannelExec使用示例:

ChannelExec channel = (ChannelExec)session.openChannel(“exec”);
decorator.command(out, command);
channel.setCommand(command);
channel.connect();

ByteArrayOutputStream errOut = new ByteArrayOutputStream();
channel.setErrStream(errOut);
InputStream in = channel.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in, “UTF-8”));
String line = null;
Writer writer = new OutputStreamWriter(out, “UTF-8”);
while ((line = reader.readLine()) != null) {

if (!getSign())
{
setSign(true);
decorator.tip(out, “操作被停止”);
return;
}

line = decorator == null ? line : decorator.line(line);
writer.write(line);
writer.flush();
}
in.close();
if(decorator != null && errOut.toByteArray().length > 0){
decorator.error(out, new String(errOut.toByteArray(), “UTF-8”));
}

channel.disconnect();
 
ChannelShell使用示例:

ChannelShell channel = (ChannelShell)session.openChannel(“shell”);
channel.connect(3000);
OutputStream output = channel.getOutputStream();
decorator.command(out, command);
output.write((command + “\n”).getBytes());
output.flush();

InputStream in = channel.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in, “UTF-8”));
String line = null;
Writer writer = new OutputStreamWriter(out, “UTF-8”);

try
{
while ((line = reader.readLine()) != null) {
line = decorator == null ? line : decorator.line(line);
writer.write(line);
writer.write(“\r\n”);
writer.flush();
for(String returnKeyWord :returnKeyWords){
if (!getSign())
{
setSign(true);
decorator.tip(out, “操作被停止”);
channel.disconnect();
return;
}

if(line.indexOf(returnKeyWord) > -1){
channel.disconnect();
return;
}
}
}
}
finally
{
try
{
if (null != in)
{
in.close();
}
}
catch(Exception e)
{

}

try
{
if (null != reader)
{
reader.close();
}
}
catch(Exception e)
{

}
}
 
ChannelSftp使用示例:

ChannelSftp channel = (ChannelSftp)session.openChannel(“sftp”);
channel.connect();
channel.cd(dst);
OutputStream output = channel.put(sourceFile.getName());
InputStream input = new FileInputStream(sourceFile);
IOUtils.copy(input, output);
input.close();
output.close();
channel.disconnect();
 
以上小编为大家介绍了JSch组件的一些概念和基本使用方法,感兴趣的同学可以动手尝试下使用JSch连接Linux服务器。后续还有更多精彩的文章,感兴趣的同学可以关注我们的微信公众号。

————————————————
版权声明:本文为CSDN博主「cdk15」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chendaike/article/details/102662626