使用方法
- 本地安装python环境,并且配置好环境变量,不会的点我
- 在本地新建auto.py然后粘贴进以下脚本,然后修改顶部注释部分的相关参数
- 打开命令行工具,cd到auto.py所在目录,然后python auto.py回车执行脚本
- 按照提示输入服务器登录密码,回车
配置
1import paramiko
2import os
3
4# —————————————————————此处配置打包相关参数———————————————————————
5# 本地项目目录
6project_path = r'E:\projects\cloud-music'
7# 项目打包后的目录,一般为dist或者build
8build_path = 'build'
9# 服务器目录
10remote_path = r'/www/cloud-music'
11# 服务器地址
12hostname = '192.168.1.225'
13# 登陆服务器的用户名
14username = 'fuck'
15# ————————————————————————配置结束—————————————————————————————
16
17
18class SSHConnect:
19 # 定义一个私有变量,用来保存ssh连接通道,初始化为None
20 __transport = None
21
22 # 初始化构造函数(主机,用户名,密码,端口,默认22)
23 def __init__(self, hostname, username, password, port=22):
24 self.hostname = hostname
25 self.port = port
26 self.username = username
27 self.password = password
28 # 创建 ssh 连接通道
29 self.connect()
30
31 # 建立ssh 连接通道,并绑定在 __transport 上
32 def connect(self):
33 try:
34 # 设置SSH 连接的远程主机地址和端口
35 self.__transport = paramiko.Transport((self.hostname, self.port))
36 # 通过用户名和密码连接SSH服务端
37 self.__transport.connect(username=self.username, password=self.password)
38 except Exception as e:
39 # 连接出错
40 print(e)
41
42 # 执行linux命令
43 def exec(self, command):
44
45 # 创建 ssh 客户端
46 ssh = paramiko.SSHClient()
47 # 指定连接的通道
48 ssh._transport = self.__transport
49
50 # 打开一个Channel并执行命令, 调用 exec_command 方法执行命令
51 stdin, stdout, stderr = ssh.exec_command(command)
52
53 # 获取命令结果,返回是二进制,需要编码一下
54 res = stdout.read().decode('utf-8')
55 # 获取错误信息
56 error = stderr.read().decode('utf-8')
57
58 # 如果没出错
59 if error.strip():
60 # 返回错误信息
61 return error
62 else:
63 # 返回结果
64 return res
65
66 # 前端打包(入参work_path为项目目录)
67 def build(self, work_path):
68 # 开始打包
69 print('_______________________________________________')
70 print('正在打包...')
71 # 打包命令
72 cmd = 'npm run build'
73 # 切换到需要项目目录
74 os.chdir(work_path)
75 # 当前项目目录下执行打包命令
76 if os.system(cmd) == 0:
77 # 打包完成
78 print('打包完成!')
79 print('开始上传文件...')
80
81 # 文件上传
82 def upload(self, local_path, target_path):
83 # 判断路径问题
84 if not os.path.exists(local_path):
85 return print('local path is not exist')
86
87 # 实例化一个 sftp 对象,指定连接的通道
88 sftp = paramiko.SFTPClient.from_transport(self.__transport)
89 # 打包后的文件路径
90 local_path = os.path.join(local_path, build_path)
91 # 本地路径转换,将windows下的 \ 转成 /
92 local_path = '/'.join(local_path.split('\\'))
93
94 # 递归上传文件
95 self.upload_file(sftp, local_path, target_path)
96
97 print('Everything is ok,Have a nice day!')
98 # 关闭连接
99 self.close()
100
101 # 递归上传文件
102 def upload_file(self, sftp, local_path, target_path):
103 # 判断当前路径是否是文件夹
104 if not os.path.isdir(local_path):
105 # 如果是文件,获取文件名
106 file_name = os.path.basename(local_path)
107 # 检查服务器文件夹是否存在
108 self.check_remote_dir(sftp, target_path)
109 # 服务器创建文件
110 target_file_path = os.path.join(target_path, file_name).replace('\\', '/')
111 # 上传到服务器
112 sftp.put(local_path, target_file_path)
113 else:
114 # 查看当前文件夹下的子文件
115 file_list = os.listdir(local_path)
116 # 遍历子文件
117 for p in file_list:
118 # 拼接当前文件路径
119 current_local_path = os.path.join(local_path, p).replace('\\', '/')
120 # 拼接服务器文件路径
121 current_target_path = os.path.join(target_path, p).replace('\\', '/')
122 # 如果已经是文件,服务器就不需要创建文件夹了
123 if os.path.isfile(current_local_path):
124 # 提取当前文件所在的文件夹
125 current_target_path = os.path.split(current_target_path)[0]
126 # 递归判断
127 self.upload_file(sftp, current_local_path, current_target_path)
128
129 # 创建服务器文件夹
130 def check_remote_dir(self, sftp, target_path):
131 try:
132 # 判断文件夹是否存在
133 sftp.stat(target_path)
134 except IOError:
135 # 创建文件夹
136 self.exec(r'mkdir -p %s ' % target_path)
137
138 # 自动化打包部署
139 def auto_deploy(self, local_path, target_path):
140 # 打包构建
141 self.build(local_path)
142 # 清空文件
143 self.clear_remote_dir(target_path)
144 # 文件上传
145 self.upload(local_path, target_path)
146
147 # 清空文件夹
148 def clear_remote_dir(self, target_path):
149 if target_path[-1] == '/':
150 cmd = f'rm -rf {target_path}*'
151 else:
152 cmd = f'rm -rf {target_path}/*'
153 self.exec(cmd)
154
155 # 关闭连接
156 def close(self):
157 self.__transport.close()
158
159 # 销毁实例
160 def __del__(self):
161 self.__transport.close()
162
163
164if __name__ == '__main__':
165 # 实例化
166 password = input("请输入服务器连接密码:")
167 ssh = SSHConnect(hostname=hostname, username=username, password=password)
168 # 自动打包部署
169 ssh.auto_deploy(project_path, remote_path)
170