使用過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伺服器。後續還有更多精彩的文章,感興趣的同學可以關注我們的微信公衆号。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL90TUaJHbXl1a1clWv5kMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLwkjN1ITN1MTMxIDMxkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)