Java 实现 SCP 携带密码拷贝文件

背景说明

涉及通过程序进行机器间的文件Copy的场景,我们一般会使用ssh连接机器,通过scp命令进行文件copy。

此种方案的前提是:机器间事先要配置免密码互通。

但是 ,如果客户现场机器数量过多,配置免密操作比较麻烦;或者处于安全考虑,客户不允许机器之间免密访问。

此时,需要另辟蹊径,找其他方案实现。

需求场景:提供机器的IP,登录用户名、登录密码,但是不配置机器间的免密登录,实现机器之间的文件传输。

Java 实现

1、工具类

ScpUtil.java

java 复制代码
package com.miracle.luna.scp;

import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.scp.client.ScpClient;
import org.apache.sshd.scp.client.ScpClientCreator;

/**
 * @author Miracle Luna
 * @date 2021/7/19
 */
public class ScpUtil {

//    private static String host = "192.168.67.48";
    private static String host = "192.168.67.39";
//    private static String host = "192.168.71.29";
    private static String username = "root";
    private static String password = "password";
    private static Integer port = 22;

//    private static String local = "F:\\miracle\\*";
    private static String local = "/home/miracle/*";
    private static String remote = "/home/luna/";
//    private static String remote = "F:\\luna\\";

    public static void scpFile(String local, String remote) throws Exception {
        long startTime = System.currentTimeMillis();

        // 创建 SSH客户端
        SshClient client = SshClient.setUpDefaultClient();
        // 启动 SSH客户端
        client.start();
        // 通过主机IP、端口和用户名,连接主机,获取Session
        ClientSession session = client.connect(username, host, port).verify().getSession();
        // 给Session添加密码
        session.addPasswordIdentity(password);
        // 校验用户名和密码的有效性
        boolean isSuccess = session.auth().verify().isSuccess();

        // 认证成功
        if (isSuccess) {
            long middleTime = System.currentTimeMillis();
            System.out.println("Connect host cost time: " + (middleTime - startTime) / 1000.0 + "s.");

            ScpClientCreator creator = ScpClientCreator.instance();
            // 创建 SCP 客户端
            ScpClient scpClient = creator.createScpClient(session);

            System.out.println("Scp beginning.");
            // ScpClient.Option.Recursive:递归copy,可以将子文件夹和子文件遍历copy
            scpClient.upload(local, remote, ScpClient.Option.Recursive);
            System.out.println("Scp finished.");

            // 释放 SCP客户端
            if (scpClient != null) {
                scpClient = null;
            }

            // 关闭 Session
            if (session != null && session.isOpen()) {
                session.close();
            }

            // 关闭 SSH客户端
            if (client != null && client.isOpen()) {
                client.stop();
                client.close();
            }
        }

        long endTime = System.currentTimeMillis();
        System.out.println("Total Cost time: " + (endTime - startTime) / 1000.0 + "s.");
    }

    public static void main(String[] args) throws Exception {
        scpFile(local, remote);
    }
}

2、运行结果

java 复制代码
Connect host cost time: 6.519s.
Scp beginning.
Scp finished.
Total Cost time: 9.569s.

3、Maven依赖

xml 复制代码
<!-- https://mvnrepository.com/artifact/org.apache.sshd/sshd-common -->
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-common</artifactId>
    <version>2.7.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.sshd/sshd-core -->
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-core</artifactId>
    <version>2.7.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.sshd/sshd-scp -->
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-scp</artifactId>
    <version>2.7.0</version>
</dependency>

补充说明

该方式适用于Linux到Linux、Linux到Windows、Windows到Linux、Windows到Windows间的文件拷贝。

(和Windows进行文件交互的前提是:Windows安装了SSH服务端,如OpenSSH,FreeSSHd,Bitvise SSH Server等)

相关推荐
Mos_x3 分钟前
计算机组成原理核心知识点梳理
java·后端
墨寒博客栈7 分钟前
Linux基础常用命令
java·linux·运维·服务器·前端
回忆是昨天里的海12 分钟前
k8s-部署springboot容器化应用
java·容器·kubernetes
INFINI Labs23 分钟前
使用 Docker Compose 轻松实现 INFINI Console 离线部署与持久化管理
java·docker·eureka·devops·docker compose·console·easyserach
Cosolar24 分钟前
国产麒麟系统 aarch64 架构 PostgreSQL 15 源码编译安装完整教程
java·后端
GalaxyPokemon32 分钟前
PlayerFeedback 插件开发日志
java·服务器·前端
天天摸鱼的java工程师1 小时前
别再写那些重复代码了!8年Java老兵教你用 Hutool 提升开发效率
java·后端
喝杯绿茶1 小时前
springboot中的事务
java·spring boot·后端
麦兜*1 小时前
多阶段构建:打造最小化的 Spring Boot Docker 镜像
java·spring boot·后端·spring cloud·docker
oak隔壁找我1 小时前
Spring Boot Starter 入门教程
java·后端