You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Python实现远程Ubuntu服务器定期(每分钟)从本地传输文件

实现本地文件定期同步到远程Ubuntu服务器的Python方案

Hey there! 要搞定每分钟把本地文件自动传到远程Ubuntu服务器的需求,用Python结合SSH工具和定时任务就能轻松实现,我给你一步步拆解:

1. 选择合适的传输工具

远程文件传输最稳妥的方式就是通过SSH协议,Python里的paramiko库完美支持SCP(基于SSH的文件传输),Ubuntu服务器默认开启SSH服务,刚好适配。

先安装依赖:

pip install paramiko schedule

schedule是用来做定时任务的,比直接用time.sleep更灵活好维护)

2. 核心上传代码实现

下面是完整的上传脚本,支持单个文件、整个目录的递归上传,还加了异常处理避免崩溃:

import paramiko
import os
import schedule
import time

def upload_files(local_path, remote_path, server_ip, username, password=None, private_key_path=None):
    # 初始化SSH客户端
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    try:
        # 连接服务器:优先用密钥登录(更安全),没有的话用密码
        if private_key_path:
            private_key = paramiko.RSAKey.from_private_key_file(private_key_path)
            ssh.connect(server_ip, username=username, pkey=private_key)
        else:
            ssh.connect(server_ip, username=username, password=password)
        
        # 打开SCP通道
        sftp = ssh.open_sftp()
        
        # 判断本地路径是文件还是目录
        if os.path.isfile(local_path):
            # 上传单个文件
            sftp.put(local_path, os.path.join(remote_path, os.path.basename(local_path)))
            print(f"已上传文件: {local_path} -> {remote_path}")
        elif os.path.isdir(local_path):
            # 递归上传目录
            for root, dirs, files in os.walk(local_path):
                # 构建远程对应的目录路径
                remote_dir = os.path.join(remote_path, os.path.relpath(root, local_path))
                # 远程目录不存在就创建
                try:
                    sftp.stat(remote_dir)
                except FileNotFoundError:
                    sftp.mkdir(remote_dir)
                    print(f"创建远程目录: {remote_dir}")
                # 上传目录里的每个文件
                for file in files:
                    local_file = os.path.join(root, file)
                    remote_file = os.path.join(remote_dir, file)
                    sftp.put(local_file, remote_file)
                    print(f"已上传文件: {local_file} -> {remote_file}")
        
        sftp.close()
        ssh.close()
    except Exception as e:
        print(f"上传出错: {str(e)}")
        if ssh.get_transport().is_active():
            ssh.close()

# 配置你的参数
LOCAL_FILES_PATH = "/path/to/your/local/files"  # 本地文件/目录路径
REMOTE_SERVER_IP = "192.168.x.x"               # 远程Ubuntu服务器IP
REMOTE_USERNAME = "your_username"              # 服务器用户名
REMOTE_PASSWORD = "your_password"              # 或者用密钥,下面注释掉密码打开密钥路径
# PRIVATE_KEY_PATH = "/path/to/your/private/key"  # 比如~/.ssh/id_rsa
REMOTE_TARGET_PATH = "/path/to/remote/target"  # 服务器上的目标路径

# 定时任务:每分钟执行一次上传
schedule.every(1).minutes.do(
    upload_files,
    local_path=LOCAL_FILES_PATH,
    remote_path=REMOTE_TARGET_PATH,
    server_ip=REMOTE_SERVER_IP,
    username=REMOTE_USERNAME,
    password=REMOTE_PASSWORD
    # 如果用密钥,把上面的password换成private_key_path=PRIVATE_KEY_PATH
)

# 让定时任务持续运行
print("开始执行定时文件同步...")
while True:
    schedule.run_pending()
    time.sleep(1)

3. 关键优化与注意事项

  • 优先用密钥登录:密码登录虽然方便,但密钥更安全。生成密钥对的命令是ssh-keygen,然后把公钥传到Ubuntu服务器的~/.ssh/authorized_keys里就行。
  • 增量上传优化:上面的脚本会每次全量上传,如果文件很多可以加个判断——对比本地文件和远程文件的修改时间或MD5哈希,只上传更新过的文件,减少带宽消耗。
  • 后台运行:如果想让脚本在终端关闭后继续运行,可以用nohup命令:
    nohup python3 your_script.py > sync_log.log 2>&1 &
    
    日志会存在sync_log.log里,方便排查问题。
  • 权限问题:确保远程服务器的目标路径有写入权限,本地文件也有读取权限。

4. 测试运行

先手动执行一次upload_files函数测试能不能正常上传,没问题再启动定时任务,这样能提前发现配置错误~

内容的提问来源于stack exchange,提问作者Esraa

火山引擎 最新活动