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实现类似ftp传输文件的网络程序示例
Apr 08 Python
Python单元测试框架unittest简明使用实例
Apr 13 Python
Python切片知识解析
Mar 06 Python
Python实现发送与接收邮件的方法详解
Mar 28 Python
python django下载大的csv文件实现方法分析
Jul 19 Python
python按行读取文件并找出其中指定字符串
Aug 08 Python
Python的互斥锁与信号量详解
Sep 12 Python
Python MySQL 日期时间格式化作为参数的操作
Mar 02 Python
Django 解决开发自定义抛出异常的问题
May 21 Python
使用Python将语音转换为文本的方法
Aug 10 Python
python 爬取B站原视频的实例代码
Sep 09 Python
Python生成九宫格图片的示例代码
Apr 14 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+xml编程之SimpleXML的应用实例
2015/01/24 PHP
php微信开发之关键词回复功能
2018/06/13 PHP
php基于协程实现异步的方法分析
2019/07/17 PHP
PHP扩展类型及安装方式解析
2020/04/27 PHP
客户端脚本中常常出现的一些问题和调试技巧
2007/01/09 Javascript
javascript URL编码和解码使用说明
2010/04/12 Javascript
JavaScript高级程序设计(第3版)学习笔记8 js函数(中)
2012/10/11 Javascript
使用jquery自定义鼠标样式满足个性需求
2013/11/05 Javascript
js+jquery实现图片裁剪功能
2015/01/02 Javascript
详解javascript中的事件处理
2015/11/06 Javascript
JavaScript基础语法之js表达式
2016/06/07 Javascript
浅谈Javascript数据属性与访问器属性
2016/07/26 Javascript
jQuery easyui刷新当前tabs的方法
2016/09/23 Javascript
vue项目中做编辑功能传递数据时遇到问题的解决方法
2016/12/19 Javascript
Vue 仿百度搜索功能实现代码
2017/02/16 Javascript
Vue.js 2.0和Cordova开发webApp环境搭建方法
2018/02/26 Javascript
[02:28]DOTA2 2015国际邀请赛中国区预选赛首日现场百态
2015/05/26 DOTA
在Python的while循环中使用else以及循环嵌套的用法
2015/10/14 Python
Python编程中的for循环语句学习教程
2015/10/14 Python
Selenium 模拟浏览器动态加载页面的实现方法
2018/05/16 Python
利用python在excel里面直接使用sql函数的方法
2019/02/08 Python
梅尔倒谱系数(MFCC)实现
2019/06/19 Python
在PyTorch中Tensor的查找和筛选例子
2019/08/18 Python
python基于FTP实现文件传输相关功能代码实例
2019/09/28 Python
Python itertools.product方法代码实例
2020/03/27 Python
用Python开发app后端有优势吗
2020/06/29 Python
python调用win32接口进行截图的示例
2020/11/11 Python
在HTML5 Canvas中放入图片和保存为图片的方法
2014/05/03 HTML / CSS
Bose法国官网:购买耳机、扬声器、家庭影院、专业音响
2017/12/21 全球购物
莫斯科隐形眼镜网上商店:Linzi
2019/07/22 全球购物
你对IPv6了解程度
2016/02/09 面试题
OSPF有什么优点?为什么OSPF比RIP收敛快?
2013/02/13 面试题
如何进行Linux分区优化
2016/09/13 面试题
2014年协会工作总结
2014/11/22 职场文书
捐款感谢信
2015/01/20 职场文书
离婚民事起诉状
2015/08/03 职场文书