python脚本从windows上传目录到linux服务器,实现一键部署

前言

最近在弄云主机的时候遇到一个问题:利用SecureCRT来上传文件很不方便,而且上传之后又得自己来部署。
所以就想着,自己写个脚本实现将文件上传到服务器,并直接通过该脚本部署(在服务端执行一些linux命令,比如重新加载上传的资源之类)
写脚本我基本都用python
网搜搜索了之后,发现python有个库:paramiko支持这些操作。


那就开始动手吧

下载paramiko

http://www.paramiko.org/installing.html
里面提示用pip命令安装(如果电脑上没有安装pip,就得先安装这个工具)

1
pip install paramiko

安装pip

pip官网:https://pip.pypa.io/en/latest/installing.html
里面提示下载文件:get-pip.py
然后运行脚本(自己进入cmd,再执行这个脚本,不要直接点开)

1
python get-pip.py

安装完之后,发现cmd里面找不到pip命令:
这里需要我们把C:\Python27\Scripts目录加到path里面去,pip就在这个目录下(python目录写你自己的)。

然后安装paramiko的时候,居然又报错了!!!
error: Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat).
Get it from http://aka.ms/vcpython27

只能根据提示继续去下载:地址


开始写脚本咯

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
# -*- coding: utf-8 -*-
import paramiko
import datetime
import os
import ConfigParser
import codecs

hostname = ""
port = 22
username = ""
password = ""
REMOTE_PATH = ""
LOCAL_PATH = ""

def loadConfig():
global hostname
global port
global username
global password
global REMOTE_PATH
global LOCAL_PATH

f = codecs.open( "config.ini" , "r" ,encoding='UTF-8');
config = ConfigParser.ConfigParser()
config.readfp(f)
hostname = config.get("global","hostname")
port = int(config.get("global","port"))
username = config.get("global","username")
password = config.get("global","password")
REMOTE_PATH = config.get("global","REMOTE_PATH")
LOCAL_PATH = config.get("global","LOCAL_PATH")

def upload(_localDir, _remoteDir):
_localDir = LOCAL_PATH
_remoteDir = LOCAL_PATH
try:
t = paramiko.Transport((hostname, port))
t.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(t)
print 'upload file start %s ' % datetime.datetime.now()
for root, dirs, files in os.walk(_localDir):
# 相对与_localDir的路径
remoteRoot = root.replace("\\", "/")
# 文件名,不包括路径
for filespath in files:
local_file = os.path.join(root, filespath)
remote_file = REMOTE_PATH + "/" +remoteRoot + "/" + filespath
remote_file = remote_file.replace("//", "/")
# print("remote_file : %s" % remote_file)
try:
sftp.put(local_file, remote_file)
except Exception, e:
sftp.mkdir(os.path.split(remote_file)[0])
sftp.put(local_file, remote_file)
print "upload %s to remote %s" % (local_file, remote_file)
for name in dirs:
remoteDir = _remoteDir +"/"+ remoteRoot +"/" + name
remoteDir = remoteDir.replace("//", "/")
print("remoteDir ", remoteDir)
try:
sftp.mkdir(remoteDir)
print "mkdir path %s" % remoteDir
except Exception, e:
pass
print 'upload file success %s ' % datetime.datetime.now()
t.close()
except Exception, e:
print e

loadConfig()
upload(LOCAL_PATH, REMOTE_PATH)

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, 22, username, password)
stdin, stdout, stderr = ssh.exec_command("du -ah " + REMOTE_PATH)
print stdout.readlines()
ssh.close()

对应的配置文件

1
2
3
4
5
6
7
[global]
hostname = 115.xxxxxx
port = 22
username = xxxxx
password = xxxxx
REMOTE_PATH = /home/xxx/
LOCAL_PATH = data1

提示
大家根据自己的需求修改下代码就可以了
PS:传文件的时候,可以先打包下,可以提高不少效率!


总结

传文件主要是通过:paramiko.SFTPClient
在服务端执行命令主要是通过:paramiko.SSHClient

转载本站文章请注明作者(xtutu)和出处 xtutu