ssh工具 (Java)

执行shell命令、下载文件...

package com.sunsheen.blockchain.admin.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Properties;

import org.apache.http.util.Asserts;

import ch.ethz.ssh2.ChannelCondition;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.StreamGobbler;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.sunsheen.blockchain.admin.common.ServersConstant;

public class SSHUtil {
    
    /**
     * 连接服务器
     * @param host
     * @param user
     * @param pwd
     * @return
     * @throws JSchException
     */
    public static synchronized Session connect(String host,String user,String pwd) throws JSchException {
        JSch jsch = new JSch();
        Session session = jsch.getSession(user, host, 22);
        session.setConfig("StrictHostKeyChecking", "no");
        // java.util.Properties config = new java.util.Properties();
        // config.put("StrictHostKeyChecking", "no");
        session.setPassword(pwd);
        session.connect();
        return session;
    }
    
    /**
     * 执行命令集
     * @param session
     * @param cmds
     * @return
     * @throws IOException
     * @throws JSchException
     */
    public static String execCommandByShell(Session session,String[] cmds)
            throws IOException, JSchException {
        String result = "";
        // 2.尝试解决 远程ssh只能执行一句命令的情况
        ChannelShell channelShell = (ChannelShell) session.openChannel("shell");
        InputStream inputStream = channelShell.getInputStream();// 从远端到达的数据都能从这个流读取到
        channelShell.setPty(true);
        channelShell.connect();

        OutputStream outputStream = channelShell.getOutputStream();// 写入该流的数据
                                                                    // 都将发送到远程端
        // 使用PrintWriter 就是为了使用println 这个方法
        // 好处就是不需要每次手动给字符加

        PrintWriter printWriter = new PrintWriter(outputStream);
        for (String cmd:cmds) {
            printWriter.println(cmd);
        }
        printWriter.println("exit");// 为了结束本次交互
        printWriter.flush();// 把缓冲区的数据强行输出
        return result;
    }
    
    /**
     * 单个文件上传
     * @param file        上传的文件
     * @param remoteFolder    服务器上存放当前文件的文件夹
     * @param uploadFileName    上传文件的名字
     */
    public static void postFile(InputStream fileStream,String remoteFolder,String uploadFileName) throws Exception{
        //上传文件的个数应该跟对应文件夹相同
        if((null==fileStream || null==remoteFolder))
            return;
        
        String username = ServersConstant.USERNAME;
        String password = ServersConstant.PASSWORD;
        String address = ServersConstant.ADDRES;
        int port = ServersConstant.PORT;
        
        ChannelSftp sftp = null;
        Channel channel = null;
        Session sshSession = null;
        try {
            //创建连接
            JSch jsch = new JSch();
            sshSession = jsch.getSession(username, address, port);
            sshSession.setPassword(password);
            //获取session
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            //得到sftp
            channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
            
            sftp.cd(remoteFolder);//进入对应存放日志文件的目录
            sftp.put(fileStream, uploadFileName);//写入文件
            
        } finally {
            //关闭sftp信道
            if (sftp != null) {
                if (sftp.isConnected()) {
                    sftp.disconnect();
                }
            }
            //关闭channel管道
            if (channel != null) {
                if (channel.isConnected()) {
                    channel.disconnect();
                }
            }
            //关闭session
            if (sshSession != null) {
                if (sshSession.isConnected()) {
                    sshSession.disconnect();
                }
            }
        }        
    }
    
    /**
     * 转换指令到服务器执行
     * @param command    要执行的指令
     */
    public static void transferCommand(String... commands){
        String romoteAddr = ServersConstant.ADDRES;
        String username = ServersConstant.USERNAME;
        String password = ServersConstant.PASSWORD;
        try {
              Connection connection = new Connection(romoteAddr);// 创建一个连接实例
              connection.connect();// Now connect
              boolean isAuthenticated = connection.authenticateWithPassword(username, password);//認證
              Asserts.check(isAuthenticated, "用戶名或密碼錯誤!");
              ch.ethz.ssh2.Session sess = connection.openSession();// 創建一個會話
              sess.requestPTY("bash");
              sess.startShell();
              InputStream stdout = new StreamGobbler(sess.getStdout());
              InputStream stderr = new StreamGobbler(sess.getStderr());
              BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(stdout));
              BufferedReader stderrReader = new BufferedReader(new InputStreamReader(stderr));
              //向服务器上输入命令
              PrintWriter out = new PrintWriter(sess.getStdin());
              for(String command : commands){
                  out.println(command);
              }
              out.close();
              sess.waitForCondition(ChannelCondition.CLOSED|ChannelCondition.EOF | ChannelCondition.EXIT_STATUS,100);
              //关闭连接
              sess.close();
              connection.close();
              stderrReader.close();
              stdoutReader.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
    }
    
    
    /**
     * 下载指定文件到本地指定文件夹oo
     * @param serversFolder    服务器文件所在目录  /opt/log
     * @param fileName            需要下载的文件名        monitor.log
     * @param localFolder        本地存放文件的文件夹 d:\logs
     */
    public static void download(String serversFolder,String fileName,String localFolder)  {
        String username = ServersConstant.USERNAME;
        String password = ServersConstant.PASSWORD;
        String address = ServersConstant.ADDRES;
        int port = ServersConstant.PORT;
        
        ChannelSftp sftp = null;
        Channel channel = null;
        Session sshSession = null;
        try {
            // 创建连接
            JSch jsch = new JSch();
            sshSession = jsch.getSession(username, address, port);
            sshSession.setPassword(password);
            // 获取session
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            // 得到sftp
            channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
            // 进入服务器文件夹
            sftp.cd(serversFolder);
            //创建本地文件夹
            File downloadFile = new File(localFolder);
            if(!downloadFile.exists())
                downloadFile.mkdirs();
            // 下载
            String serversFile = serversFolder +"/"+ fileName;
            sftp.get(serversFile,localFolder);
            System.out.println(fileName+"已下载到:"+localFolder);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭sftp信道
            if (sftp != null) {
                if (sftp.isConnected()) {
                    sftp.disconnect();
                }
            }
            // 关闭channel管道
            if (channel != null) {
                if (channel.isConnected()) {
                    channel.disconnect();
                }
            }
            // 关闭session
            if (sshSession != null) {
                if (sshSession.isConnected()) {
                    sshSession.disconnect();
                }
            }
        }
    }
    
}
原文地址:https://www.cnblogs.com/Soy-technology/p/12035331.html