如何通过本地控制让远程A直接向远程B传输文件(可使用JSch)?
实现远程A直接向远程B传输文件的方案
核心思路
本地仅作为指令触发端,通过SSH连接远程A,在A上执行直接向远程B传输文件的操作,完全跳过本地作为缓冲区的环节,实现远程A → 远程B的直接传输。
关键技术点
- 远程A与B的无交互SSH认证:在远程A上生成SSH密钥对,将公钥添加到远程B的
~/.ssh/authorized_keys中,确保A可以免密登录B,这是自动化的前提。 - SSH远程执行命令:本地通过SSH客户端(如JSch)连接远程A,直接在A的环境中执行文件传输命令(scp/sftp)或脚本。
- 无交互批处理传输:使用scp的非交互式模式,或编写sftp批处理脚本,避免手动输入交互信息。
伪代码示例
方案1:本地用JSch触发远程A执行scp命令
// 本地代码:连接远程A并执行scp传输命令 JSch jsch = new JSch(); Session sessionA = jsch.getSession("userA", "hostA", 22); sessionA.setPassword("passA"); // 或用密钥认证登录A sessionA.setConfig("StrictHostKeyChecking", "no"); sessionA.connect(); // 在远程A上执行scp命令,将A上的文件直接传到B String scpCommand = "scp /path/on/A/file.txt userB@hostB:/path/on/B/"; ChannelExec channelExec = (ChannelExec) sessionA.openChannel("exec"); channelExec.setCommand(scpCommand); channelExec.connect(); // 等待命令执行完成,处理输出 InputStream in = channelExec.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line; while ((line = reader.readLine()) != null) { // 处理执行日志 } channelExec.disconnect(); sessionA.disconnect();
方案2:远程A上部署脚本,本地触发执行
- 在远程A上创建
sftp_transfer.sh脚本:
#!/bin/bash # 无交互sftp批处理脚本 sftp userB@hostB << EOF put /path/on/A/file.txt /path/on/B/ quit EOF
给脚本添加执行权限:chmod +x sftp_transfer.sh
- 本地用JSch触发脚本执行:
JSch jsch = new JSch(); Session sessionA = jsch.getSession("userA", "hostA", 22); sessionA.setPassword("passA"); sessionA.setConfig("StrictHostKeyChecking", "no"); sessionA.connect(); ChannelExec channelExec = (ChannelExec) sessionA.openChannel("exec"); // 执行A上的传输脚本 channelExec.setCommand("/path/on/A/sftp_transfer.sh"); channelExec.connect(); // 处理执行输出... channelExec.disconnect(); sessionA.disconnect();
替代技术选型(不局限JSch)
- 本地用
ssh命令行工具(结合Java的ProcessBuilder调用),直接远程执行A上的传输命令,无需依赖JSch。 - 远程A使用Python的
paramiko库编写传输脚本,本地触发执行,适合非Java环境。
内容的提问来源于stack exchange,提问作者user275616
相关产品推荐
相关产品推荐

