天天看點

Java程式連接配接Linux伺服器核心元件:JSch

使用過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伺服器。後續還有更多精彩的文章,感興趣的同學可以關注我們的微信公衆号。

Java程式連接配接Linux伺服器核心元件:JSch

繼續閱讀