使用Python paramiko跨服务器迁移目录报IsADirectoryError如何解决
报错原因
paramiko 自带的 sftp.put() 方法仅支持传输单个文件,无法直接处理目录,所以当你传入本地目录路径时就会触发 IsADirectoryError 错误。另外你报错日志里的远程路径存在拼写错误:/home/destinatiob/workspace/vddir 中的 destinatiob 应为 destination,也可能额外引发路径不存在的问题。
解决方案
方案1:自定义递归目录传输函数
适配原有SFTP传输逻辑,新增递归遍历目录、自动创建远程目录、逐文件传输的能力,完整可运行代码如下:
import paramiko import os def sftp_put_dir(sftp, local_dir, remote_dir): for item in os.listdir(local_dir): local_full_path = os.path.join(local_dir, item) remote_full_path = os.path.join(remote_dir, item) # 处理子目录 if os.path.isdir(local_full_path): # 自动创建远程目录,忽略已存在报错 try: sftp.mkdir(remote_full_path) except IOError: pass # 递归传输子目录内容 sftp_put_dir(sftp, local_full_path, remote_full_path) # 传输单个文件 else: sftp.put(local_full_path, remote_full_path) # SSH连接逻辑 client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect('你的目标服务器IP', username='你的用户名', password='你的密码') print("开始传输目录") sftp = client.open_sftp() # 先创建顶层目标目录 try: sftp.mkdir('/home/destination/workspace/vddir') except IOError: pass # 调用自定义方法传输整个目录 sftp_put_dir(sftp, '/home/source/workspace/vddir', '/home/destination/workspace/vddir') sftp.close() client.close() print("目录传输完成")
方案2:调用系统命令传输(大目录更推荐)
如果源服务器和目标服务器网络互通,直接通过SSH执行scp/rsync系统命令的传输效率远高于逐文件SFTP传输,适合大体积目录迁移场景,示例代码如下:
import paramiko client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect('你的目标服务器IP', username='你的用户名', password='你的密码') # 执行scp命令从源服务器拉取完整目录,按需替换源服务器的登录信息 command = 'scp -r 源服务器用户名@源服务器IP:/home/source/workspace/vddir /home/destination/workspace/' stdin, stdout, stderr = client.exec_command(command) # 等待命令执行完毕 exit_code = stdout.channel.recv_exit_status() if exit_code == 0: print("目录传输成功") else: print(f"传输失败,错误信息:{stderr.read().decode()}") client.close()
内容的提问来源于stack exchange,提问作者TONY FRANK C
相关产品推荐
相关产品推荐

