paramiko模块是python中很重要的模块,他的功能呢主要分为两大块功能。一个是模拟SSH功能登录到远程主机上执行命令。一个是模拟SFTP功能传输文件。

paramiko支持密码登陆方式和免密码的私钥登录方式。

密码登陆方式代码如下:

#!/usr/bin/env python
# coding:utf-8
import paramiko
# 创建SSH对象
ssh = paramiko.SSHClient()
# 访问未知主机时候的策略,允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='172.16.1.101', port=22, username='wgw', password='123456')
# 执行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
result = stdout.read()
#打印远程命令的执行结果
print result
# 关闭连接
ssh.close()

上面的代码很简单,有点运维基础肯定都能看到明白。唯一要注意的就是遇到未知主机的时候,ssh的处理策略。这个要设置好。不然know_hosts文件里没有的主机在第一次登陆的时候会被拒绝掉。


使用SSH秘钥登陆的代码如下:

#!/usr/bin/env python
# coding:utf-8
import paramiko
#指定用于登录其他主机的私钥文件的存储位置 
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器的时候通过pkey关键字替代password关键字
ssh.connect(hostname='172.16.1.101', port=22, username='wgw', pkey=private_key)
# 执行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
result = stdout.read()
# 关闭连接
ssh.close()

通过秘钥登陆的用户和密码登陆大同小异,只需定义私钥文件的位置然后引用pkey关键字就好了。


使用密码和SFTP命令上传和下载文件的代码如下:

import paramiko
transport = paramiko.Transport(('hostname',22))
transport.connect(username='wupeiqi',password='123')
sftp = paramiko.SFTPClient.from_transport(transport)
# 将location.py 上传至服务器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py')
# 将remove_path 下载到本地 local_path
sftp.get('remove_path', 'local_path') 
transport.close()


使用秘钥和SFTP命令上传和下载文件的代码如下:

import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
#创建transport对象 
transport = paramiko.Transport(('hostname', 22))
#通过connect方法创建远程连接
transport.connect(username='wgw', pkey=private_key )
#调用SFTPClient填写刚才创建的transport对象来创建一个sftp对象 
sftp = paramiko.SFTPClient.from_transport(transport)
# 将location.py 上传至服务器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py')
# 将remove_path 下载到本地 local_path
sftp.get('remove_path', 'local_path')
transport.close()

代码不难,但是从代码里可以到实现ssh和sftp的时候。创建连接时使用的方法不一样。

SSH是使用SSHClient()里面的connect方法创建的

ssh = paramiko.SSHClient()
ssh.connect(hostname='172.16.1.101', port=22, username='wgw', password='123456')

SFTP使用的Transport()里面的connetc方法创建的

transport = paramiko.Transport(('172.16.1.101',22))
transport.connect(username='wgw',password='123456')

两个都是connect方法有什么区别和联系呢?其实paramiko.SSHClient().connect()这个方法的内部实现调用的就是Transport().connect()这个方法。所以可以认为Transport()是paramiko里面创建连接的通用方法。那仙子我们通过Transport方法来改写一下SSH的功能

import paramiko
#调用Transport方法与实现SFTP的连接功能一样,创建连接
transport = paramiko.Transport(('172.16.1.101', 22))
transport.connect(username='wgw', password='123456')
#这个方法还是必须要加上的还需要调用exec_command()等方法使用
ssh = paramiko.SSHClient()
#用这一句代替ssh.connect()方法
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command('df')
print stdout.read()
transport.close()

这样如果我们要实现一个可以远程操作主机的程序,那么程序的远程执行命令和传输文件等功能就可以写到一个类里面了。示意代码如下:

import paramiko
class my_paramiko(object):
    def __init__(self,ip,port):
        self.ip=ip
        self.port=int(port)
        #定义登录被管理主机时使用的用户
        self.manager='admin'
        #指定登录各个主机时所使用的秘钥文件位置
        self.key=paramiko.RSAKey.from_private_key_file('/home/wgw/.ssh/id_rsa')
    def connect(self):
        """
        这个方法用于调用paramiko创建连接。
        """
        #创建连接实例
        transport = paramiko.Transport((self.ip,self.port))
        transport.connect(username=self.manager, pkey=self.key)
        self.__transport=transport
    def cmd(self,user_cmd):
        """
        这个方法用于实现在远程主机上执行命令
        """ 
        #调用连接方法连接服务器
        self.connect()
        #调用paramiko的SSH方法实现远程执行命令
        ssh = paramiko.SSHClient()
        ssh._transport=self.__transport
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        #远程执行命令
        ssh.exec_command(user_cmd)
        #执行命令后管理远程连接
        ssh.close()
 
    def excute_upload(self,local_file,remote_file):
        """
        这个方法用于实现,上传文件到远程的功能。要求用户输入本地文件路径和远程文件
        路径。
        """
        #调用连接方法连接服务器
        self.connect()
        #调用paramiko的sftp方法实现远程上传命令
        sftp = paramiko.SFTPClient.from_transport(self.__transport)
        #调用sftp.put方法把本地文件上传到服务器上。
        sftp.put(local_file,remote_file)

通过这种方式,就可以把功能很好的结合一来。