实现通过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模块。

 

参考文章:

  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 
痞子泰 
阅读(4752
评论(0
编辑 
收藏 
举报

版权声明:本文为pizitai原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/pizitai/p/6398632.html