paramiko模块的安装和使用(含上传本地文件或文件夹到服务器,以及下载服务器文件到本地)
实现通过Python脚本将本地文件上传服务器,以及将服务器文件下载到本地
安装和使用分两步介绍:
介绍一下,本文的运行环境是win7 64位 和python 2.7 。
安装:
WIN7_64位 安装python-ssh访问模块(paramiko)的安装教程,本人亲测下面教程没问题的,所以可以放心按步骤进行操作
参考地址:
http://jingyan.baidu.com/article/fdbd4277c629c9b89e3f4828.html
使用:
1. paramiko连接
使用paramiko模块有两种连接方式,一种是通过paramiko.SSHClient()函数,另外一种是通过paramiko.Transport()函数。
方法一:
1 import paramiko
2 ssh = paramiko.SSHClient()
3 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
4 ssh.connect("某IP地址",22,"用户名", "口令")
方法二:
1 import paramiko
2 t = paramiko.Transport(("主机","端口"))
3 t.connect(username = "用户名", password = "口令")
如果连接远程主机需要提供密钥,上面第二行代码可改成:
t.connect(username = "用户名", password = "口令", hostkey="密钥")
2. 上传本地文件到服务器:
1 #!/usr/bin/python
2 # -*- coding:utf-8 -*-
3
4 import paramiko
5
6 if __name__ == \'__main__\':
7 host_ip = \'10.*.*.*\'
8 port = \'22\'
9 username1 = \'***\'
10 password1 = \'***\'
11 t = paramiko.Transport(host_ip, port)
12 t.connect(username=username1, password=password1)
13 sftp = paramiko.SFTPClient.from_transport(t)
14 remotepath = r\'/home/temp/b.txt\'
15 localpath = r\'D:\aaa\a.txt\'
16 sftp.put(localpath, remotepath)
17 t.close()
3. 下载服务器文件到本地:
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 import paramiko
4 import os
5
6 def remote_scp(host_ip, port, remote_path, local_path, username, password):
7 port= port or 22
8 t = paramiko.Transport((host_ip, port))
9 t.connect(username=username, password=password)
10 sftp = paramiko.SFTPClient.from_transport(t)
11 src = remote_path
12 des = local_path
13 sftp.get(src, des)
14 t.close()
15
16 if __name__ == \'__main__\':
17 host_ip = \'10.*.*.*\'
18 remote_path = \'/home/temp/a.txt\'
19 local_path = r\'D:\aaa\a.txt\'
20 part_path= os.path.dirname(local_path)
21 if not os.path.exists(part_path):
22 os.makedirs(part_path)
23 username = \'***\'
24 password = \'****\'
25 remote_scp(host_ip, 22, remote_path, local_path, username, password)
4. ssh连接服务器:
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 import paramiko
4
5 def ssh2(ip, username, passwd, cmd):
6 try:
7 ssh = paramiko.SSHClient()
8 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
9 ssh.connect(ip, 22, username, passwd, timeout=50)
10 stdin, stdout, stderr = ssh.exec_command(cmd)
11 # stdin.write("Y") #简单交互,输入 ‘Y’
12 print stdout.read()
13 # for x in stdout.readlines():
14 # print x.strip("\n")
15 print \'%s\tOK\n\' % (ip)
16 ssh.close()
17 except:
18 print \'%s\tError\n\' % (ip)
19
20
21 if __name__ == \'__main__\':
22 host_ip = \'10.*.*.*\'
23 port = \'22\'
24 username1 = \'***\'
25 password1 = \'***\'
26 ssh2(host_ip, username1, password1, \'less /home/temp/a.txt\')
5. 目录下多个文件的上传下载:
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 import paramiko, datetime, os
4
5 host_ip = \'10.*.*.*\'
6 username1 = \'***\'
7 password1 = \'****\'
8 port = 22
9 local_dir = \'d:/aaa\'
10 remote_dir = \'/home/temp/Templates\'
11 try:
12 t = paramiko.Transport(host_ip, port)
13 t.connect(username=username1, password=password1)
14 sftp = paramiko.SFTPClient.from_transport(t)
15 files = os.listdir(local_dir) # 上传多个文件
16 # files = sftp.listdir(remote_dir) # 下载多个文件
17 for f in files:
18 print \'\'
19 print \'#########################################\'
20 print \'Beginning to download file from %s %s \' % (host_ip, datetime.datetime.now())
21 print \'Downloading file:\', (remote_dir + \'/\' + f)
22 # sftp.get(remote_dir + \'/\' + f, os.path.join(local_dir, f)) # 下载多个文件
23 sftp.put(os.path.join(local_dir, f), remote_dir + \'/\' + f) # 上传多个文件
24 print \'Download file success %s \' % datetime.datetime.now()
25 print \'\'
26 print \'##########################################\'
27 t.close()
28 except Exception:
29 print "connect error!"
6. 递归上传目录里面的文件或是文件夹到多个服务器
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 import paramiko
4 import datetime
5 import os
6
7
8 def upload(local_dir, remote_dir, hostname, port, username, password):
9 try:
10 t = paramiko.Transport((hostname, port))
11 t.connect(username=username, password=password)
12 sftp = paramiko.SFTPClient.from_transport(t)
13 print(\'upload file start %s \' % datetime.datetime.now())
14 for root, dirs, files in os.walk(local_dir):
15 print(\'[%s][%s][%s]\' % (root, dirs, files))
16 for filespath in files:
17 local_file = os.path.join(root, filespath)
18 print(11, \'[%s][%s][%s][%s]\' % (root, filespath, local_file, local_dir))
19 a = local_file.replace(local_dir, \'\').replace(\'\\\', \'/\').lstrip(\'/\')
20 print(\'01\', a, \'[%s]\' % remote_dir)
21 remote_file = os.path.join(remote_dir, a).replace(\'\\\', \'/\')
22 print(22, remote_file)
23 try:
24 sftp.put(local_file, remote_file)
25 except Exception as e:
26 sftp.mkdir(os.path.split(remote_file)[0])
27 sftp.put(local_file, remote_file)
28 print("66 upload %s to remote %s" % (local_file, remote_file))
29 for name in dirs:
30 local_path = os.path.join(root, name)
31 print(0, local_path, local_dir)
32 a = local_path.replace(local_dir, \'\').replace(\'\\\', \'/\').lstrip(\'/\')
33 print(1, a)
34 print(1, remote_dir)
35 # remote_path = os.path.join(remote_dir, a).replace(\'\\\', \'/\')
36 remote_path = remote_dir + a
37 print(33, remote_path)
38 try:
39 sftp.mkdir(remote_path)
40 print(44, "mkdir path %s" % remote_path)
41 except Exception as e:
42 print(55, e)
43 print(\'77,upload file success %s \' % datetime.datetime.now())
44 t.close()
45 except Exception as e:
46 print(88, e)
47
48
49 if __name__ == \'__main__\':
50 # 选择上传到那个服务器
51 serverlist = [\'服务器00\', \'服务器01\', \'服务器02\']
52 for i in range(len(serverlist)):
53 print ("序号:%s 对应的服务器为:%s" % (i, serverlist[i]))
54 num = raw_input("请输入对应服务器的序号:")
55 num = int(num)
56 hostname = [\'10.*.*.*\', \'10.*.*.*\', \'10.*.*.*\']
57 username = [\'root\', \'root\', \'root\']
58 password = [\'***\', \'***\', \'***\']
59 port = [22, 22, 22]
60
61 local_dir = r\'D:\aaa\'
62 remote_dir = \'/home/temp/dd/\'
63 upload(local_dir, remote_dir, hostname=hostname[num], port=port[num], username=username[num],
64 password=password[num])
7. 利用paramiko实现ssh的交互式连接
以下是通过paramiko模块直接用ssh协议登陆到远程服务器的操作代码,这里先定义一个interactive模块(即 interactive.py),
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 import socket
4 import sys
5
6 # windows does not have termios...
7 try:
8 import termios
9 import tty
10
11 has_termios = True
12 except ImportError:
13 has_termios = False
14
15
16 def interactive_shell(chan):
17 if has_termios:
18 posix_shell(chan)
19 else:
20 windows_shell(chan)
21
22
23 def posix_shell(chan):
24 import select
25 oldtty = termios.tcgetattr(sys.stdin)
26 try:
27 tty.setraw(sys.stdin.fileno())
28 tty.setcbreak(sys.stdin.fileno())
29 chan.settimeout(0.0)
30 while True:
31 r, w, e = select.select([chan, sys.stdin], [], [])
32 if chan in r:
33 try:
34 x = chan.recv(1024)
35 if len(x) == 0:
36 print \'\r\n*** EOF\r\n\',
37 break
38 sys.stdout.write(x)
39 sys.stdout.flush()
40 except socket.timeout:
41 pass
42 if sys.stdin in r:
43 x = sys.stdin.read(1)
44 if len(x) == 0:
45 break
46 chan.send(x)
47 finally:
48 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
49
50
51 # thanks to Mike Looijmans for this code
52 def windows_shell(chan):
53 import threading
54 sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n")
55
56 def writeall(sock):
57 while True:
58 data = sock.recv(256)
59 if not data:
60 sys.stdout.write(\'\r\n*** EOF ***\r\n\r\n\')
61 sys.stdout.flush()
62 break
63 sys.stdout.write(data)
64 sys.stdout.flush()
65
66 writer = threading.Thread(target=writeall, args=(chan,))
67 writer.start()
68 try:
69 while True:
70 d = sys.stdin.read(1)
71 if not d:
72 break
73 chan.send(d)
74 except EOFError:
75 # user hit ^Z or F6
76 pass
写一个ssh_inter.py的交互主程序调用interactive模块,代码如下:
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 import paramiko
4 import interactive
5
6 if __name__ == \'__main__\':
7 host_ip = \'10.*.*.*\'
8 username1 = \'***\'
9 password1 = \'***\'
10 port = 22
11 # 记录日志写到本地文件中
12 paramiko.util.log_to_file(r\'D:/aaa/wu.txt\')
13 # 建立ssh连接
14 ssh = paramiko.SSHClient()
15 ssh.load_system_host_keys()
16 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
17 ssh.connect(host_ip, port=22, username=username1, password=password1, compress=True)
18 # 建立交互式shell连接
19 channel = ssh.invoke_shell()
20 # 建立交互式管道
21 interactive.interactive_shell(channel)
22 # 关闭连接
23 channel.close()
24 ssh.close()
总结:
paramiko模块是一个比较强大的ssh连接模块,以上的示例只是列出了该模块的一些简单的使用方法,还可以使用threading模块加块程序并发的速度;也可以使用configparser模块处理配置文件,而我们将所有IP、用户信息操作都放入配置文件;使用setproctitle模块为执行的程序加一个容易区分的title等。
同样,虽然连fabric这样大名鼎鼎的软件使用的ssh都是用paramiko模块进行的封装,不过你依然可以选择不使用它,你也可以选择pexpect模块实现封装一个简易的ssh连接工具、或者使用同样比较火的salt-ssh模块。
参考文章: