博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python3之paramiko模块
阅读量:4708 次
发布时间:2019-06-10

本文共 7093 字,大约阅读时间需要 23 分钟。

1、paramiko模块介绍

paramiko模块提供了基于ssh连接,进行远程登录服务器执行命令和上传下载文件的功能。这是一个第三方的软件包,使用之前需要安装。

2、paramiko的使用方法

(1)基于用户名和密码的sshclient方式登陆

#!/usr/bin/env python#coding:utf8import paramiko#创建sshclient对象ssh = paramiko.SSHClient()#允许将信任的主机自动加入到host_allow 列表,此方法必须放在connect方法的前面ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())#调用connect方法连接服务器ssh.connect(hostname='172.16.32.129',port=2323,username='root',password='123.com')while True:    input_command = input('>>>:')    if input_command == 'quit':        break    #执行命令,输出结果在stdout中,如果是错误则放在stderr中    stdin,stdout,stderr = ssh.exec_command(input_command)    result = stdout.read() #read方法读取输出结果    if len(result) == 0:  #判断如果输出结果长度等于0表示为错误输出        print(stderr.read())    else:        print(str(result,'utf-8'))ssh.close()

封装方法,隐藏属性:

#config.ini文件[ssh]host=172.16.32.129port=2323user=rootpwd=123.comtimeout=1.1#封装ssh类#!/usr/bin/env python#coding:utf8import configparser,paramikoclass parmikoclient(object):    def __init__(self,ini_file):        self.config=configparser.ConfigParser()        self.config.read(ini_file)        self.host = self.config.get('ssh','host')        self.port = self.config.get('ssh', 'port')        self.user = self.config.get('ssh', 'user')        self.pwd = self.config.get('ssh', 'pwd')        self.timeout = self.config.get('ssh', 'timeout')        self.client=paramiko.SSHClient()        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())        self.client.connect(hostname=self.host,port=self.port,username=self.user,password=self.pwd,timeout=float(self.timeout))    def run_ssh(self,cmd_command):        # 执行命令,输出结果在stdout中,如果是错误则放在stderr中        stdin,stdout,stderr = self.client.exec_command(cmd_command)        result = stdout.read()  # read方法读取输出结果        if len(result) == 0:  # 判断如果输出结果长度等于0表示为错误输出            print(stderr.read().decode())        else:            print(str(result, 'utf-8'))    def close(self):        self.client.close()if __name__ == '__main__':    client_cmd = parmikoclient('config.ini')    while True:        cmd_input=input('>>>:')        client_cmd.run_ssh(cmd_input)        if cmd_input == 'quit':            client_cmd.close()

通过transport方式登录:

#!/usr/bin/env python#coding:utf8import paramiko#实例化一个transport对象transport = paramiko.Transport(('172.16.32.129',2323))#建立连接transport.connect(username='root',password='123')#建立ssh对象ssh = paramiko.SSHClient()#绑定transport到ssh对象ssh._transport=transport#执行命令stdin,stdout,stderr=ssh.exec_command('df')#打印输出print(stdout.read().decode())#关闭连接transport.close()

(2)基于密钥的sshclient方式登陆

#!/usr/bin/env python#coding:utf8#必须先将公钥文件传输到服务器的~/.ssh/authorized_keys中import paramiko# 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数pkey = paramiko.RSAKey.from_private_key_file('id_rsa_1024')#建立连接ssh = paramiko.SSHClient()#允许将信任的主机自动加入到known_hosts列表ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())ssh.connect(hostname='172.16.32.129',port=2323,username='root',pkey=pkey) #指定密钥连接#执行命令stdin,stdout,stderr=ssh.exec_command('free -m')print(stdout.read().decode())ssh.close()

以上需要确保被访问的服务器对应用户.ssh目录下有authorized_keys文件,也就是将服务器上生成的公钥文件保存为authorized_keys。并将私钥文件作为paramiko的登陆密钥

transport封装密钥登陆:

#!/usr/bin/env python#coding:utf8#必须先将公钥文件传输到服务器的~/.ssh/authorized_keys中import paramiko# 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数pkey = paramiko.RSAKey.from_private_key_file('id_rsa_1024')#创建transport对象绑定主机和端口,指定用户和密钥连接transport = paramiko.Transport(('172.16.32.129',2323))transport.connect(username='root',pkey=pkey)ssh = paramiko.SSHClient()ssh._transport = transport  #类属性赋值#允许将信任的主机自动加入到known_hosts列表ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())#执行命令stdin,stdout,stderr=ssh.exec_command('free -m')print(stdout.read().decode())ssh.close()

(3)SFTP文件传输

#!/usr/bin/env python#coding:utf8import paramiko#实例化transport对象,并建立连接transport = paramiko.Transport(('172.16.32.129',2323))transport.connect(username='root',password='123.com')#实例化sftp对象,指定连接对象sftp = paramiko.SFTPClient.from_transport(transport)#上传文件sftp.put(localpath='id_rsa_1024',remotepath='/root/idrsa1024.txt')#下载文件sftp.get(remotepath='/root/idrsa1024.txt',localpath='idrsa1024_back.txt')#关闭连接transport.close()

实现一个类似xshell工具的功能,登录以后可以输入命令回车后就返回结果:

import paramikoimport osimport selectimport sys# 建立一个sockettrans = paramiko.Transport(('192.168.2.129', 22))# 启动一个客户端trans.start_client()# 如果使用rsa密钥登录的话'''default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')prikey = paramiko.RSAKey.from_private_key_file(default_key_file)trans.auth_publickey(username='super', key=prikey)'''# 如果使用用户名和密码登录trans.auth_password(username='super', password='super')# 打开一个通道channel = trans.open_session()# 获取终端channel.get_pty()# 激活终端,这样就可以登录到终端了,就和我们用类似于xshell登录系统一样channel.invoke_shell()# 下面就可以执行你所有的操作,用select实现# 对输入终端sys.stdin和 通道进行监控,# 当用户在终端输入命令后,将命令交给channel通道,这个时候sys.stdin就发生变化,select就可以感知# channel的发送命令、获取结果过程其实就是一个socket的发送和接受信息的过程while True:    readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])    # 如果是用户输入命令了,sys.stdin发生变化    if sys.stdin in readlist:        # 获取输入的内容        input_cmd = sys.stdin.read(1)        # 将命令发送给服务器        channel.sendall(input_cmd)    # 服务器返回了结果,channel通道接受到结果,发生变化 select感知到    if channel in readlist:        # 获取结果        result = channel.recv(1024)        # 断开连接后退出        if len(result) == 0:            print("\r\n**** EOF **** \r\n")            break        # 输出到屏幕        sys.stdout.write(result.decode())        sys.stdout.flush()# 关闭通道channel.close()# 关闭链接trans.close()

支持tab自动补全

import paramikoimport osimport selectimport sysimport ttyimport termios'''实现一个xshell登录系统的效果,登录到系统就不断输入命令同时返回结果支持自动补全,直接调用服务器终端'''# 建立一个sockettrans = paramiko.Transport(('192.168.2.129', 22))# 启动一个客户端trans.start_client()# 如果使用rsa密钥登录的话'''default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')prikey = paramiko.RSAKey.from_private_key_file(default_key_file)trans.auth_publickey(username='super', key=prikey)'''# 如果使用用户名和密码登录trans.auth_password(username='super', password='super')# 打开一个通道channel = trans.open_session()# 获取终端channel.get_pty()# 激活终端,这样就可以登录到终端了,就和我们用类似于xshell登录系统一样channel.invoke_shell()# 获取原操作终端属性oldtty = termios.tcgetattr(sys.stdin)try:    # 将现在的操作终端属性设置为服务器上的原生终端属性,可以支持tab了    tty.setraw(sys.stdin)    channel.settimeout(0)    while True:        readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])        # 如果是用户输入命令了,sys.stdin发生变化        if sys.stdin in readlist:            # 获取输入的内容,输入一个字符发送1个字符            input_cmd = sys.stdin.read(1)            # 将命令发送给服务器            channel.sendall(input_cmd)        # 服务器返回了结果,channel通道接受到结果,发生变化 select感知到        if channel in readlist:            # 获取结果            result = channel.recv(1024)            # 断开连接后退出            if len(result) == 0:                print("\r\n**** EOF **** \r\n")                break            # 输出到屏幕            sys.stdout.write(result.decode())            sys.stdout.flush()finally:    # 执行完后将现在的终端属性恢复为原操作终端属性    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)# 关闭通道channel.close()# 关闭链接trans.close()

 

转载于:https://www.cnblogs.com/zhangxinqi/p/8372774.html

你可能感兴趣的文章
Oauth支持的5类 grant_type 及说明
查看>>
C#中用DateTime的ParseExact方法解析日期时间(excel中使用系统默认的日期格式)
查看>>
W3100SM-S 短信猫代码发送 上
查看>>
netty接收大文件的方法
查看>>
软件工程设计之四则运算
查看>>
SpringMVC @ResponseBody 406
查看>>
Partial Tree UVALive - 7190(完全背包)
查看>>
Ubuntu安装搜狗拼音教程
查看>>
Happy Number
查看>>
Sqlserver 系统视图简单说明
查看>>
vue中ESlint报错
查看>>
NetCore2.0 RozarPage自动生成增删改查
查看>>
0816 1459 json & pickle ,目录导入,目录规范
查看>>
Servlet 生命周期
查看>>
HDU 1398
查看>>
如何恢复oracle中已删除的表
查看>>
双向BFS(转)
查看>>
【最短路】Dijkstra+ 链式前向星+ 堆优化(优先队列)
查看>>
linux下实现keepalived+nginx高可用
查看>>
Html Agility Pack解析Html(C#爬虫利器)
查看>>