痞子泰

导航

 

安装和使用分两步介绍:

       介绍一下,本文的运行环境是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模块。

 

参考文章:

  1. http://www.111cn.net/phper/python/67973.htm    
  2. http://blog.csdn.net/wawa8899/article/details/52965077#

 

posted on 2017-02-14 17:39  痞子泰  阅读(5342)  评论(0编辑  收藏  举报