当前位置: 首页 > news >正文

【跨服务器的数据自动化下载--安装公钥,免密下载】

跨服务器的数据自动化下载

    • 功能介绍:
    • 上代码:

发现好久没写csdn了,说多了都是泪~~
以后会更新一些自动化工作的脚本or 小tricks,欢迎交流。在这里插入图片描述分享一个最近在业务上写的较为实用的自动化脚本,可以批量从远端服务器下载指定数据到当前程序运行服务器,无需每次都输入密码,通过集成安装公钥的功能,实现免密下载。这个方式适合这种不能安装 sshpass又想全自动化的环境。

功能介绍:

第一次运行:会提示输入一次远端 服务器 的密码(安装公钥)。安装完成后立即用免密下载。
以后运行:直接免密下载,全自动。
后续所有下载脚本全自动化,不用再输入任何密码,也不依赖额外工具。
以从远端服务器(账户:abc)下载数据为例。

上代码:

#!/usr/bin/env python3
import sys
import os
import subprocess
import tempfile
import shutildef check_key_auth(remote_username, remote_host, private_key_path):"""检查是否已配置免密"""result = subprocess.run(['ssh', '-i', private_key_path, '-o', 'BatchMode=yes', '-o', 'StrictHostKeyChecking=no',f'{remote_username}@{remote_host}', 'echo ok'],stdout=subprocess.PIPE, stderr=subprocess.PIPE)return result.returncode == 0def install_pubkey(remote_username, remote_host, private_key_path):"""将本地公钥写入远端 authorized_keys(会要求输入密码一次)"""pubkey_path = private_key_path + '.pub'if not os.path.exists(pubkey_path):print(f"未找到公钥文件 {pubkey_path}")return Falsewith open(pubkey_path, 'r') as f:pubkey_content = f.read().strip()print(f"正在将公钥写入 {remote_host},需要输入 {remote_username} 的密码...")cmd = ['ssh', f'{remote_username}@{remote_host}',f'mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo "{pubkey_content}" >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys']return subprocess.run(cmd).returncode == 0def download_files_batch(remote_username, remote_host, private_key_path, files_to_download):"""批量下载实现:1. 在本地创建一个临时目录 tmpdir2. 用 single scp 命令把所有 remote:files 下载到 tmpdir(scp 支持多个 source + 单个 destination directory)3. 将 tmpdir 下的文件移动到各自的目标位置"""# 先保证目标本地目录存在(创建父目录)for _, local_path in files_to_download:os.makedirs(os.path.dirname(local_path), exist_ok=True)tmpdir = tempfile.mkdtemp(prefix='download_')try:# 构造 scp 命令:scp -i key user@host:/path/to/file1 user@host:/path/to/file2 ... <tmpdir>scp_cmd = ['scp', '-i', private_key_path, '-o', 'StrictHostKeyChecking=no']for remote_path, _ in files_to_download:scp_cmd.append(f'{remote_username}@{remote_host}:{remote_path}')scp_cmd.append(tmpdir)  # scp 要求最后是目标目录print("执行 scp,目标临时目录:", tmpdir)print("scp 命令:", ' '.join(scp_cmd))proc = subprocess.run(scp_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)if proc.returncode != 0:print("批量 scp 失败,错误信息:")print(proc.stderr.decode(errors='ignore'))return False# scp 成功,把文件从 tmpdir 移动到最终位置for remote_path, local_path in files_to_download:fname = os.path.basename(remote_path)src = os.path.join(tmpdir, fname)if not os.path.exists(src):print(f"警告:远端文件 {remote_path} 未被下载到临时目录({src} 不存在)")# 继续处理其它文件continueshutil.move(src, local_path)print(f"已移动:{src} -> {local_path}")print("全部文件处理完成。")return Truefinally:# 清理临时目录(如果里面还有剩余文件,会一并删除)try:shutil.rmtree(tmpdir)except Exception as e:print("清理临时目录时出错:", e)def main():if len(sys.argv) != 2:print("用法: python fully_auto_download.py <date>")sys.exit(1)date = sys.argv[1]remote_host = "" ##你需要获取数据的远端ipremote_username = "abc"private_key_path = '/.ssh/id_rsa'files_to_download = [(f"/data/{date[:4]}/{date}_000000_000000.csv",f"/save/{date}_000000_000000.csv"),## 此处省略其他需要下载的数据]# 检查免密if not check_key_auth(remote_username, remote_host, private_key_path):print("未检测到免密,开始安装公钥...")if not install_pubkey(remote_username, remote_host, private_key_path):print("公钥安装失败,请检查密码是否正确或远端权限设置。")sys.exit(1)if not check_key_auth(remote_username, remote_host, private_key_path):print("免密配置仍然失败,请手动检查。")sys.exit(1)print("免密配置成功!")# 一次性批量下载ok = download_files_batch(remote_username, remote_host, private_key_path, files_to_download)if not ok:print("批量下载出现问题,退回逐个下载尝试。")# 如果批量下载失败,可以回退到逐个 scp(免密已经配置好了,不会再要求密码)for remote_path, local_path in files_to_download:try:os.makedirs(os.path.dirname(local_path), exist_ok=True)scp_cmd = ['scp', '-i', private_key_path, '-o', 'StrictHostKeyChecking=no',f'{remote_username}@{remote_host}:{remote_path}', local_path]subprocess.run(scp_cmd, check=True)print(f"下载成功: {local_path}")except subprocess.CalledProcessError as e:print(f"下载失败: {local_path}, 错误: {e}")if __name__ == "__main__":main()
http://www.xdnf.cn/news/1287559.html

相关文章:

  • 【CSS3】录音中。。。
  • 【oracle闪回查询】记录字段短时间被修改的记录
  • 【AI绘画】Stable Diffusion webUI 常用功能使用技巧
  • css之再谈浮动定位float(深入理解篇)
  • react+vite来优化下每次使用hook函数都要引入的情况
  • React (react-amap)高德地图使用(加标记、缩放、缩略图)
  • 荣耀手机无法连接win11电脑,错误消息:“无法在此设备上加载驱动程序 (hn_usbccgpfilter.sys)。”解决方案
  • OBOO鸥柏丨智能会议平板教学查询一体机交互式触摸终端招标投标核心标底参数要求
  • SQL Server增加对UTF-8的支持
  • Baumer高防护相机如何通过YoloV8深度学习模型实现纸箱的实时检测计数(C#代码UI界面版)
  • 谷歌ADK接入文件操作MCP
  • 力扣47:全排列Ⅱ
  • 基于Python的《红楼梦》文本分析与机器学习应用
  • 力扣 hot100 Day71
  • vivo Pulsar 万亿级消息处理实践(2)-从0到1建设 Pulsar 指标监控链路
  • [激光原理与应用-254]:理论 - 几何光学 - 自动对焦的原理
  • 数据结构:中缀到后缀的转换(Infix to Postfix Conversion)
  • Flutter GridView的基本使用
  • Java 工厂方法模式
  • 【项目设计】高并发内存池
  • 北京-4年功能测试2年空窗-报培训班学测开-第七十四天-线下面试-聊的很满意但可能有风险-等信吧
  • cuda排序算法--双调排序(Bitonic_Sort)
  • web前端第二次作业
  • 开发避坑指南(23):Tomcat高版本URL特殊字符限制问题解决方案(RFC 7230 RFC 3986)
  • TF-IDF:信息检索与文本挖掘的统计权重基石
  • 多奥电梯智能化解决方案的深度解读与结构化总结,内容涵盖系统架构、功能模块、应用场景与社会价值四大维度,力求全面展示该方案的技术先进性与应用前景。
  • Agent智能体基础
  • vue3大事件
  • Linux随记(二十二)
  • 本地(macOS)和服务器时间不同步导致的 Bug排查及解决