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