paramiko

  *paramiko需要PyCrypto模块的支持

  paramiko支持通过SSH协议进行一些操作,比如远程执行命令,上下传文件等等

  用法:

  ①  远程命令

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #指定当对方主机没有本机公钥的情况时应该怎么办,AutoAddPolicy表示自动在对方主机保存下本机的秘钥
ssh.connect('ip',22,'user','passwd') #SSH端口默认22,可改
stdin,stdout,stderr = ssh.exec_command("命令内容") #这三个得到的都是类文件对象
outmsg,errmsg = stdout.read(),stderr.read() #读一次之后,stdout和stderr里就没有内容了,所以一定要用变量把它们带的信息给保存下来,否则read一次之后就没有了
if errmsg == "":
print outmsg
ssh.close()

  ②  文件交流

tra = paramiko.Transport(('ip',22))    #参数是一个tuple
tra.connect(username='...',password='...') #一定要指明参数名的username和password。否则会报错str has no attribute 'get_name'
sftp = paramiko.SFTPClient.from_transport(tra)
sftp.put('本地路径','远程路径') #上传文件
sftp.get('远程路径','本地路径') #下载文件
tra.close()

  需要注意的是在put和get方法中,两个路径都是需要完整的(要带文件名!)

  sftp的put和get方法还有callback这个参数。这个参数指定一个函数对象,这个函数应该接受两个int型参数,分别代表了已上传/已下载的字节数;总的要上传/下载的字节数。利用callback的指定可以做出一个类似进度条的功能。另外,还需要注意的是callback会在传输完成之前不断地被调用但是具体是怎么样的时机下调用我不是很清楚,需要研究下paramiko的源码。但是可以确定的一点是这个callback函数也是在主线程中调用的,所以最好不要在里面写什么sleep,这样会导致整个传输过程变慢的。

■  Transport的更多扩展

  今天想通过python做一个SSH模拟终端。想法非常简单,就是通过SSHClient类建立连接然后进行命令和返回的交互嘛。不过发生了很多问题,去网上一找才发现,原来SSHClient类的exec_command方法是个单session包装的方法。即调用这个方法只能执行一趟命令,执行完成之后就断开了连接,再次执行时又是新的session。比如:

  ssh.exec_command('cd /tmp;pwd')的返回是/tmp,但如果把cd和pwd分成两个exec_command写的话,pwd最终返回的是HOME目录,这表明了exec_command的单会话特性。那么怎么样才能从更底层开始建立命令交互的通信? 网上小查了一种方法还是需要Transport这个我们之前在SFTP时候用的类。

  做法:

tran = paramiko.Transport(sock=(ip,22))
tran.connect(username='xxx',password='xxx')
channel = tran.open_session()
channel.get_pty()
channel.invoke_shell() channel.send('ls\n')
result = ''
while True:
time.sleep(0.5)
res = channel.recv(65535).decode('utf8')
result += res
if result:
sys.stdout.write(result.strip('\n'))
if res.endswith('# ') or res.endswith('$ '):
break

  通过这样的方式搭建出来的一个SSH命令通道是和Xshell这种软件建立出来的终端差不多的,比如有终端命令行提示符,也支持cd等命令。

  在获取命令运行的返回(recv方法的返回)时,我们用了一个while True的逐次取数据的方式。这么做的一个好处就是当返回比较多比较大的时候可以顺利读取完全。其实这么写也是有其必要性在里面的。如果直接在这个代码的循环外面直接recv一下,返回得到的会是'\r\n'而不是ls返回的文件信息。什么原理不清楚但是既然while True这个方式有必要性又有优点的话就可以考虑用下。

  跳出循环的方式是判断返回的结尾是不是终端命令提示符的结尾#+"空格"或者$+"空格",这种判断方法比较不健壮。网上也有用正则匹配或者其他的一些方法来识别返回结果读取到头了,可参考。这种方法建立的SSH通道的话,是自带命令行提示符的,而且每条命令的返回实质上是“真的返回”+"\n"+"命令提示符",所以可以做到每一个命令返回之后后面就有命令提示符。

  另一方面,这个通道也并不是很万能的,比如对通过stdin进行交互要怎么做目前我还没有找到办法、因此也就也意味着对vim,crontab -e之类的对交互有需求的软件就不是支持很好了。

■  更多扩展

●  在connect方法里还有参数timeout = float设置连接超时时间

  在connect方法中,还可用参数pkey指定本机私钥文件用于身份验证,内容可以是个PKey类对象。也可以用key_filename = '路径' 这个参数来指定一个文件。而在SSHClient类还有方法load_system_host_keys用于指定对方主机存放本机公钥的位置,默认不加参数的话是将这个位置设置为~/.ssh/known_hosts。SSHClient类对象connect之前,先用load_system_host_keys指定本机公钥存放位置,再在connect的时候指明本机私钥的话,就不用password,只要username就可以登录了。

●  关于set_missing_host_key_policy

  这个方法的参数有三种选择,分别对应三种当对方主机没有在相关文件中找到本机的公钥时做的动作:

  paramiko.AutoAddPolicy()  自动添加本机的公钥和主机名进相关文件

  paramiko.RejectPolicy()  自动拒绝未知的主机名和密钥,“未知”指的是没有在相关文件中有记录的主机

  paramiko.WarningPolicy()  和AutoAdd没差,只不过在出现没有记录的情况时警告一下

●  SFTPClient类除了上面提到的那些方法以外,还有:

  sftp.mkdir('路径',mode)  #mode不用加引号,直接写755之类的即可,方法直接创建目录并按mode设置其权限

  sftp.remove('路径')  #删除某目录

  sftp.stat("文件路径")  #获取文件信息

  sftp.listdir("路径")  #以列表方式返回目录下的内容

  以上这些方法和exec_command执行一些特定的命令是差不多的,实践的时候也不必一棵树吊死在exec_command上,也可以适当考虑这些方法。

●  ssh.exec_command的异步原理

  据我估计ssh.exec_command应该是单独开一条线程来远程执行命令,而当我们对命令的输出不感兴趣,在exec_command执行之后不调用read来收集远程返回的信息的话,那么这个线程是不阻塞的。这是个小坑的地方。比如下面两个例子,ssh是一个已经配置好的SSHClient对象:

stdin,stdout,stderr = ssh.exec_command("sleep 5s;echo foo")
stdin,stdout,stderr = ssh.exec_command("echo bar")
out,err = stdout.read(),stderr.read()
if err:
print err
else:
print out
#这种情况下的输出只有bar
######另一种情况######
stdin,stdout,stderr = ssh.exec_command("sleep 5s;echo foo")
out,err = stdout.read(),stderr.read()
stdin,stdout,stderr = ssh.exec_command("echo bar")
out,err = stdout.read(),stderr.read()
if err:
print err
else:
print out
#这种情况下先等5秒然后输出foo和bar

  可以看到第一种情况中,没有读取stdout等的信息,那么本地程序直接往下执行,不管之前的命令是否还未给出结果,而第二种情况,由于我要读取内容,所以必须等到上一条命令执行完成给出结果本地才继续跑下一条命令。

  ●  stdin的用法

  之前由于基本上都是从服务器上面读数据,对于stdin这个变量一直感觉很鸡肋。直到那天要批量改服务器密码。。试了一下果然stdin是可以拿来进行write的。记得在write的时候要适当插入回车\n来模拟敲回车的过程,否则很可能会出现SSH被堵塞的情况。比如改密码这个过程:

##前面配置过程省略##
stdin,stdout,stderr = ssh.exec_command("passwd")
stdin.write("old_password\nnew_password\nnew_password\n") #因为密码要确认,所以要输两遍
out,err = stdout.read(),stderr.read()
if err != '':
print err
else:
print out

【Python】 SSH连接的paramiko的更多相关文章

  1. Python ssh连接Linux服务器报Incompatible ssh peer (no acceptable kex algorithm) 解决方法

    python通过ssh连接linux服务器,部分服务器出现如下异常 03:50:48.725 FAIL ftp operation failed, Incompatible ssh peer (no ...

  2. python远程连接paramiko 模块和堡垒机实现

    paramiko使用 paramiko模块是基于python实现了SSH2远程安全连接,支持认证和密钥方式,可以实现远程连接.命令执行.文件传输.中间SSH代理功能 安装 pip install pa ...

  3. [转]python3之paramiko模块(基于ssh连接进行远程登录服务器执行命令和上传下载文件的功能)

    转自:https://www.cnblogs.com/zhangxinqi/p/8372774.html 阅读目录 1.paramiko模块介绍 2.paramiko的使用方法 回到顶部 1.para ...

  4. Python实现多种SSH连接与文件传输

    Python实现SSH控制 使用Python进行基于口令认证的连接: 1 #加载paramiko包 2 import paramiko 3 #创建新的SSH对象 4 Client=paramiko.S ...

  5. Python实现SSH连接远程服务器

    首先需要安装paramiko模块 #-*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" import paramiko ssh = p ...

  6. python ssh

    使用python包paramiko实现通过ssh的安全远程访问 使用pip下载安装paramiko,提示会缺一个crypto包,用pip将这个包也安好,python就可以正常引用paramiko了 一 ...

  7. Python学习总结 06 paramiko 远程执行命令

    有时会需要在远程的机器上执行一个命令,并获得其返回结果.对于这种情况,python 可以很容易的实现. 1 工具 Python paramiko 1) Paramiko模块安装 在Linux的Term ...

  8. 一步一步学Python(2) 连接多台主机执行脚本

    最近在客户现场,每日都需要巡检大量主机系统的备库信息.如果一台台执行,时间浪费的就太冤枉了. 参考同事之前写的一个python脚本,配合各主机上写好的shell检查脚本,实现一次操作得到所有巡检结果. ...

  9. python实战第一天-paramiko模块并练习

    操作系统 Ubuntu 15.10 IDE & editor JetBrains PyCharm 5.0.2 ipython3 Python版本 python-3.4.3 安装paramiko ...

随机推荐

  1. R︱foreach+doParallel并行+联用迭代器优化内存+并行机器学习算法

    要学的东西太多,无笔记不能学~~ 欢迎关注公众号,一起分享学习笔记,记录每一颗"贝壳"~ --------------------------- 接着之前写的并行算法paralle ...

  2. 运行项目Tomcat报错

    1.具体报错如下: Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds. If the serve ...

  3. web开发性能优化---安全篇

    1.权限管理 从模块.表单.数据审核.功能按钮全面数据安全验证及管理. 2.ip验证 数据接口访问进行IP校验 3.登录.操作日志.程序安全日志  系统所有用户登录.操作全部日志记录. 程序安全日志操 ...

  4. Python与RabbitMQ交互

    RabbitMQ 消息队列 成熟的中间件RabbitMQ.ZeroMQ.ActiveMQ等等 RabbitMQ使用erlang语言开发,使用RabbitMQ前要安装erlang语言 RabbitMQ允 ...

  5. CF374 Journey

    技不如人甘拜下风 这题网上说法有 建反向边和先拓扑 都是为了每个点之前将其前驱都遍历到 #include<bits/stdc++.h> using namespace std; typed ...

  6. xml文件的规则

    一,规则 1.1,样本 <?xml version="1.0" encoding="utf-8"?> <contactList> < ...

  7. Aspose实现Office转PDF (ASP.NET)

    0.添加Aspose的DLL 1.可以直接去官网下载,不过默认是带水印的,如需去除水印可以购买 2.当然也可以在国内的一些下载站下载 3.将Aspose.Cells.dll.Aspose.Words. ...

  8. Java中使用UDP实现简单的聊天功能

    通过DatagramSocket类来实现.此类表示用来发送和接收数据报包的套接字. 发送端代码如下: import java.io.IOException; import java.net.*; im ...

  9. 图文详解AO打印(标准模式)

    一.概述   AO打印是英文Active-Online Print的简称,也称主动在线打印.打印前支持AO通讯协议的AO打印机(购买地址>>)首先通过普通网络与C-Lodop服务保持在线链 ...

  10. 如何使用mysqldump备份数据库

    一.背景 在开发项目中,数据库是核心资产.除了做主备冗余增加可靠性外,定期备份数据也是必须的. 使用mysqldump备份数据具有操作简单,备份和恢复时间短的优点(mysqldump备份数据生成的是批 ...