Python paramiko模块的使用示例


Posted in Python onApril 11, 2018

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

1 基于用户名和密码的 sshclient 方式登录

# 建立一个sshclient对象
ssh = paramiko.SSHClient()
# 允许将信任的主机自动加入到host_allow 列表,此方法必须放在connect方法的前面
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 调用connect方法连接服务器
ssh.connect(hostname='192.168.2.129', port=22, username='super', password='super')
# 执行命令
stdin, stdout, stderr = ssh.exec_command('df -hl')
# 结果放到stdout中,如果有错误将放到stderr中
print(stdout.read().decode())
# 关闭连接
ssh.close()

2 基于用户名和密码的 transport 方式登录

方法1是传统的连接服务器、执行命令、关闭的一个操作,有时候需要登录上服务器执行多个操作,比如执行命令、上传/下载文件,方法1则无法实现,可以通过如下方式来操作

# 实例化一个transport对象
trans = paramiko.Transport(('192.168.2.129', 22))
# 建立连接
trans.connect(username='super', password='super')

# 将sshclient的对象的transport指定为以上的trans
ssh = paramiko.SSHClient()
ssh._transport = trans
# 执行命令,和传统方法一样
stdin, stdout, stderr = ssh.exec_command('df -hl')
print(stdout.read().decode())

# 关闭连接
trans.close()

3 基于公钥密钥的 SSHClient 方式登录

# 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数
pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345')
# 建立连接
ssh = paramiko.SSHClient()
ssh.connect(hostname='192.168.2.129',
      port=22,
      username='super',
      pkey=pkey)
# 执行命令
stdin, stdout, stderr = ssh.exec_command('df -hl')
# 结果放到stdout中,如果有错误将放到stderr中
print(stdout.read().decode())
# 关闭连接
ssh.close()

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

4 基于密钥的 Transport 方式登录

# 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数
pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345')
# 建立连接
trans = paramiko.Transport(('192.168.2.129', 22))
trans.connect(username='super', pkey=pkey)

# 将sshclient的对象的transport指定为以上的trans
ssh = paramiko.SSHClient()
ssh._transport = trans

# 执行命令,和传统方法一样
stdin, stdout, stderr = ssh.exec_command('df -hl')
print(stdout.read().decode())

# 关闭连接
trans.close()
##### 传文件 SFTP ###########

# 实例化一个trans对象# 实例化一个transport对象
trans = paramiko.Transport(('192.168.2.129', 22))
# 建立连接
trans.connect(username='super', password='super')

# 实例化一个 sftp对象,指定连接的通道
sftp = paramiko.SFTPClient.from_transport(trans)
# 发送文件
sftp.put(localpath='/tmp/11.txt', remotepath='/tmp/22.txt')
# 下载文件
# sftp.get(remotepath, localpath)
trans.close()

5 实现输入命令立马返回结果的功能

以上操作都是基本的连接,如果我们想实现一个类似xshell工具的功能,登录以后可以输入命令回车后就返回结果:

import paramiko
import os
import select
import sys

# 建立一个socket
trans = 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()

6 支持tab自动补全

import paramiko
import os
import select
import sys
import tty
import termios

'''
实现一个xshell登录系统的效果,登录到系统就不断输入命令同时返回结果
支持自动补全,直接调用服务器终端

'''
# 建立一个socket
trans = 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()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
讲解python参数和作用域的使用
Nov 01 Python
python实现的文件夹清理程序分享
Nov 22 Python
在Python的Flask框架中实现单元测试的教程
Apr 20 Python
用Python实现一个简单的能够上传下载的HTTP服务器
May 05 Python
详解Python3中的Sequence type的使用
Aug 01 Python
Python网络编程之TCP套接字简单用法示例
Apr 09 Python
对python中数据集划分函数StratifiedShuffleSplit的使用详解
Dec 11 Python
详解如何管理多个Python版本和虚拟环境
May 10 Python
selenium跳过webdriver检测并模拟登录淘宝
Jun 12 Python
使用Python中的reduce()函数求积的实例
Jun 28 Python
python cv2在验证码识别中应用实例解析
Dec 25 Python
如何使用scrapy中的ItemLoader提取数据
Sep 30 Python
pandas string转dataframe的方法
Apr 11 #Python
Python实现统计给定列表中指定数字出现次数的方法
Apr 11 #Python
DataFrame中的object转换成float的方法
Apr 10 #Python
pandas object格式转float64格式的方法
Apr 10 #Python
python 处理dataframe中的时间字段方法
Apr 10 #Python
python调用API实现智能回复机器人
Apr 10 #Python
python读取文本中数据并转化为DataFrame的实例
Apr 10 #Python
You might like
PHP.MVC的模板标签系统(五)
2006/09/05 PHP
php利用单例模式实现日志处理类库
2014/02/10 PHP
PHP正则表达式替换站点关键字链接后空白的解决方法
2014/09/16 PHP
php正则preg_replace_callback函数用法实例
2015/06/01 PHP
php获取当前url地址的方法小结
2017/01/10 PHP
PHP实现的二分查找算法实例分析
2017/12/19 PHP
新浪刚打开页面出来的全屏广告代码
2007/04/02 Javascript
兼容FireFox 的 js 日历 支持时间的获取
2009/03/04 Javascript
JS按位非(~)运算符与~~运算符的理解分析
2011/07/31 Javascript
javascript 三种方法实现获得和设置以及移除元素属性
2013/03/20 Javascript
javascript间隔刷新的简单实例
2013/11/14 Javascript
JavaScript函数的4种调用方法详解
2014/04/22 Javascript
谈谈js中的prototype及prototype属性解释和常用方法
2015/11/25 Javascript
JS常见创建类的方法小结【工厂方式,构造器方式,原型方式,联合方式等】
2017/04/01 Javascript
详解Next.js页面渲染的优化方案
2019/01/27 Javascript
vue.js高德地图实现热点图代码实例
2019/04/18 Javascript
jquery 时间戳转日期过程详解
2019/10/12 jQuery
jQuery单页面文字搜索插件jquery.fullsearch.js的使用方法
2020/02/04 jQuery
[06:53]DOTA2每周TOP10 精彩击杀集锦vol.3
2014/06/25 DOTA
修改Python的pyxmpp2中的主循环使其提高性能
2015/04/24 Python
python爬取51job中hr的邮箱
2016/05/14 Python
浅谈使用Python变量时要避免的3个错误
2017/10/30 Python
python实现壁纸批量下载代码实例
2018/01/25 Python
Python 实现向word(docx)中输出
2020/02/13 Python
Python 实现将numpy中的nan和inf,nan替换成对应的均值
2020/06/08 Python
Feelunique中文官网:欧洲最大化妆品零售电商
2020/07/10 全球购物
第一范式(1NF)、第二范式(2NF)和第三范式(3NF)之间的区别是什么?
2016/04/28 面试题
酒店应聘自荐信
2013/11/09 职场文书
英语简历自我评价
2014/01/26 职场文书
创先争优一句话承诺
2014/05/29 职场文书
党员反对四风思想汇报范文
2014/10/25 职场文书
专职安全员岗位职责
2015/04/11 职场文书
2015年前台接待工作总结
2015/05/04 职场文书
严以律己专题学习研讨会发言材料
2015/11/09 职场文书
golang生成vcf通讯录格式文件详情
2022/03/25 Golang
Python中使用Opencv开发停车位计数器功能
2022/04/04 Python