sftp案例
# 案例
# -*- coding: utf-8 -*-
import traceback
import os
import stat
import logging
import paramiko
class SftpFile(object):
def __init__(self, ip, port, username, pwd):
self.ip = ip
self.port = port
self.username = username
self.pwd = pwd
self.sftp = self.init_sftp()
def init_sftp(self):
sf = paramiko.Transport((self.ip, self.port))
sf.connect(username=self.username, password=self.pwd)
return paramiko.SFTPClient.from_transport(sf)
# 判断sftp服务端文件路径是否存在,若不存在则创建
def create_dir(self, remote_dir):
try:
if stat.S_ISDIR(self.sftp.stat(remote_dir).st_mode): # 如果remote_dir存在且为目录,则忽略
pass
except Exception:
self.make_dirs(remote_dir)
logging.info("在远程[{}]上创建目录:{}".format(self.ip, remote_dir))
# 从根目录创建多级文件夹
def make_dirs(self, remote_dir):
self.sftp.chdir('/')
for dir_item in remote_dir.split('/'):
if not dir_item:
continue
try:
self.sftp.chdir(dir_item)
except Exception:
self.sftp.mkdir(dir_item)
self.sftp.chdir(dir_item)
def sftp_upload(self, local_dir, remote_dir):
if os.path.isdir(local_dir):
self.create_dir(remote_dir)
elif os.path.isfile(local_dir):
self.create_dir(os.path.dirname(remote_dir))
self.upload(local_dir, remote_dir)
def sftp_upload_list(self, local_files, remote_files):
for index, value in enumerate(local_files):
self.sftp_upload(value, remote_files[index])
# 上传
def upload(self, local_dir, remote_dir):
if os.path.isdir(local_dir): # 判断本地local_dir是否为目录
for f in os.listdir(remote_dir):
remote_dir_tmp = os.path.join(remote_dir, f)
local_dir_tmp = os.path.join(remote_dir, f)
if os.path.isdir(local_dir_tmp): # 如果本地local_dir_tmp为目录,则对远程sftp服务器进行判断
self.create_dir(remote_dir_tmp) # 判断sftp服务端文件目录是否存在,若不存在则创建
self.sftp_upload(local_dir_tmp, remote_dir_tmp)
else:
tmp_remote_file = remote_dir + '.tmp' # 先存为.tmp文件
try:
self.sftp.put(local_dir, tmp_remote_file)
logging.info("upload file success:{}".format(remote_dir))
except Exception:
logging.error('upload file fail:{}'.format(remote_dir))
logging.info(traceback.format_exc())
raise
try:
self.sftp.posix_rename(tmp_remote_file, tmp_remote_file[:-4]) # 重命名
logging.info("sftp rename success:{} to {}".format(tmp_remote_file, tmp_remote_file[:-4]))
except Exception:
logging.error("sftp rename fail:{} to {}".format(tmp_remote_file, tmp_remote_file[:-4]))
logging.info(traceback.format_exc())
raise
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.sftp.close()
if __name__ == '__main__':
localDir = 'sftp_file.py' # 本地文件或目录
remoteDir = '/data/tmp/sftp_file.py' # 远程文件或目录(注意远程路径要存在)
with SftpFile('', 22, '', '') as sf:
sf.sftp_upload(localDir, remoteDir)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
上次更新: 2023/09/04, 18:39:45