-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscp-rsync.py
executable file
·145 lines (120 loc) · 3.9 KB
/
scp-rsync.py
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python3
import argparse
import subprocess
# -3, -T, -S is not supported in rsync
def colon(path: str):
flag = False
if path.startswith(':'):
return None
if path.startswith('['):
flag = True
limit = len(path)
for c in range(limit):
if c < limit:
if path[c] == '@' and path[c + 1] == '[':
flag = True
if path[c] == ']' and path[c + 1] == ':' and flag:
return c + 1
if path[c] == ':' and not flag:
return c
if path[c] == '/':
return None
return None
def make_cmd(path):
n = colon(path)
if n:
cmd = ['ssh', path[0:n], 'test -d ' + "'" + path[n + 1:] + "'"]
else:
cmd = ['test', '-d', path]
return cmd
if __name__ == '__main__':
ssh_options = ''
rsync_options = ['--copy-links', '--progress']
recursive = False
skip_dir_check = False
parser = argparse.ArgumentParser()
parser.add_argument('--skip-dir-check', action='store_true')
parser.add_argument('-4', action='store_true')
parser.add_argument('-6', action='store_true')
parser.add_argument('-A', action='store_true')
parser.add_argument('-B', action='store_true')
parser.add_argument('-C', action='store_true')
parser.add_argument('-p', action='store_true')
parser.add_argument('-r', action='store_true')
parser.add_argument('-q', action='store_true')
parser.add_argument('-v', action='store_true')
parser.add_argument('-c', nargs=1, type=str)
parser.add_argument('-F', nargs=1, type=str)
parser.add_argument('-i', nargs=1, type=str)
parser.add_argument('-J', nargs=1, type=str)
parser.add_argument('-l', nargs=1, type=int)
parser.add_argument('-o', nargs=1, type=str)
parser.add_argument('-P', nargs=1, type=int)
parser.add_argument('srcs', nargs='+', type=str)
parser.add_argument('dst', nargs=1, type=str)
args = vars(parser.parse_args())
if args['skip_dir_check']:
skip_dir_check = True
if args['4']:
ssh_options += ' -4'
if args['6']:
ssh_options += ' -6'
if args['A']:
ssh_options += ' -o FowardAgent=Yes'
if args['B']:
ssh_options += ' -o BatchMode=Yes'
if args['C']:
ssh_options += ' -C'
if args['p']:
rsync_options += ['-p', '-t', '-U']
if args['q']:
rsync_options += ['-q']
if args['r']:
rsync_options += ['-r']
recursive = True
if args['v']:
rsync_options += ['-v']
if args['c']:
ssh_options += f' -c {args["c"][0]}'
if args['F']:
ssh_options += f' -F {args["F"][0]}'
if args['i']:
ssh_options += f' -i {args["i"][0]}'
if args['J']:
ssh_options += f' -J {args["J"][0]}'
if args['l']:
bw = args["l"][0]
if bw != 0:
bw = bw // 8
if bw == 0:
bw = 1
rsync_options += [f'--bwlimit={bw}']
if args['o']:
ssh_options += f' -o {args["o"][0]}'
if args['P']:
ssh_options += f' -p {args["P"][0]}'
srcs = args['srcs']
dst = args['dst']
if not skip_dir_check:
exist_dst = False
cmd = make_cmd(dst[0])
if cmd:
try:
subprocess.run(cmd, check=True)
exist_dst = True
except subprocess.CalledProcessError:
pass
for i, src in enumerate(srcs):
if recursive:
src = src.rstrip('/')
srcs[i] = src
if not src.endswith('/') and not exist_dst:
cmd = make_cmd(src)
try:
subprocess.run(cmd, check=True)
srcs[i] = src + '/'
except subprocess.CalledProcessError:
pass
rsync_cmd = ['rsync'] + rsync_options + ['-e'] + \
[f'ssh {ssh_options}'] + srcs + dst
subprocess.run(rsync_cmd)