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 循环while和for in简单实例
Aug 16 Python
Python基于tkinter模块实现的改名小工具示例
Jul 27 Python
Python中Scrapy爬虫图片处理详解
Nov 29 Python
python flask中静态文件的管理方法
Mar 20 Python
numpy 进行数组拼接,分别在行和列上合并的实例
May 08 Python
浅谈PYTHON 关于文件的操作
Mar 19 Python
使用python获取邮箱邮件的设置方法
Sep 20 Python
使用opencv将视频帧转成图片输出
Dec 10 Python
Python换行与不换行的输出实例
Feb 19 Python
Python图像处理库PIL的ImageFont模块使用介绍
Feb 26 Python
小 200 行 Python 代码制作一个换脸程序
May 12 Python
微信小程序调用python模型
Apr 21 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
3
2006/10/09 PHP
PHP管理依赖(dependency)关系工具 Composer 安装与使用
2014/08/18 PHP
PHP预定义超全局数组变量小结
2018/08/20 PHP
js操作ajax返回的json的注意问题!
2010/02/23 Javascript
JavaScript实现页面滚动图片加载(仿lazyload效果)
2011/07/22 Javascript
javascript函数以及基础写法100多条实用整理
2013/01/13 Javascript
jQuery中使用each处理json数据
2015/04/23 Javascript
用Node.js通过sitemap.xml批量抓取美女图片
2015/05/28 Javascript
网页收藏夹显示ICO图标(代码少)
2015/08/04 Javascript
JS动态日期时间的获取方法
2015/09/28 Javascript
JavaScript使用DeviceOne开发实战(二) 生成调试安装包
2015/12/01 Javascript
使用Angular.js开发的注意事项
2016/10/19 Javascript
使用原生的javascript来实现轮播图
2017/02/24 Javascript
slideToggle+slideup实现手机端折叠菜单效果
2017/05/25 Javascript
用React-Native+Mobx做一个迷你水果商城APP(附源码)
2017/12/25 Javascript
React父子组件间的传值的方法
2018/11/13 Javascript
原生js实现无缝轮播图
2020/01/11 Javascript
JavaScript实现简单日历效果
2020/09/11 Javascript
利用Python绘制数据的瀑布图的教程
2015/04/07 Python
Python实现保证只能运行一个脚本实例
2015/06/24 Python
python的继承知识点总结
2018/12/10 Python
python+selenium 鼠标事件操作方法
2019/08/24 Python
Python容器使用的5个技巧和2个误区总结
2019/09/26 Python
python自动下载图片的方法示例
2020/03/25 Python
详解python日志输出使用配置文件格式
2021/02/10 Python
怎么处理XML的中文问题
2015/03/26 面试题
艺术节主持词
2014/04/02 职场文书
《美丽的丹顶鹤》教学反思
2014/04/22 职场文书
计算机毕业生自荐信
2014/06/12 职场文书
医院领导班子四风对照检查材料
2014/09/27 职场文书
演讲开头怎么书写?
2019/08/06 职场文书
用Python爬取某乎手机APP数据
2021/06/15 Python
MySQL如何使用使用Xtrabackup进行备份和恢复
2021/06/21 MySQL
MySQL中日期型单行函数代码详解
2021/06/21 MySQL
Python实现DBSCAN聚类算法并样例测试
2021/06/22 Python
redis sentinel监控高可用集群实现的配置步骤
2022/04/01 Redis