python paramiko长连接_【Python】 SSH连接的paramiko

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 == "":printoutmsg

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= ''

whileTrue:

time.sleep(0.5)

res= channel.recv(65535).decode('utf8')

result+=resifresult:

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()iferr:printerrelse:printout#这种情况下的输出只有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()iferr:printerrelse:printout#这种情况下先等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 != '':printerrelse:print out

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502196.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php 共享内存列队,php中对共享内存,消息队列的操作

消息队列中的数据同样受到大小的约束,具体约束范围可通过msg_stat_queue的msg_qbytes看到。这段代码唯一有点小改动的地方就在接受消息时,指定了MSG_IPC_NOWAIT,不然如果目标队列没有数据,默认会一直等待。 一般会用到共享内存或消…

python文件路径拼接多出斜杠_浅谈python中拼接路径os.path.join斜杠的问题

浅谈python中拼接路径os.path.join斜杠的问题调试程序的过程中,发现通过os.path.join拼接的路径出现了反斜杠directory1/opt/apps/upgradePackagedirectory2icp_v1.8.0directory3os.path.join(directory1,directory2)print(directory3 : %s %directory3)执行结果dir…

matlab约当消去法,Gauss消去法解线性方程组(Matlab)

clear;clc;% Gauss消去法解线性方程组A[3 -5 6 4 -2 -3 8;1 1 -9 15 1 -9 2;2 -1 7 5 -1 6 11;-1 1 3 2 7 -1 -2;4 3 1 -7 2 1 1;2 9 -8 11 -1 -4 -1;7 2 -1 2 7 -1 9];%系数矩阵b[11 2 29 9 5 8 25];%n维向量yinv(A)*b %matlab的计算结果nlength(b);%方程个数nxzeros(n,1);%…

动感灯箱制作流程培训_广告立体灯箱的特点有哪些?

随着广告业的发展,灯箱广告行业也在突飞猛进。在灯箱广告屏的设计与制作中,为了追求真实感和艺术性,采用彩印或摄影喷绘;也有人用特种纸、塑料板(膜)、灯箱布等进行丝网印刷制作灯箱图片,并根据成本和耐候性要求选择制作方法和灯箱…

MATLAB仿真TSC在哪里找,-bash:tsc:找不到命令

我正在使用MAC并尝试安装TypeScript . 我使用安装打字稿sudo npm install -g typescript以下是结果Password:/Users//node/bin/tsc -> /Users//node/lib/node_modules/typescript/bin/tsc/Users//node/bin/tsserver -> /Users//node/lib/node_modules/typescript/bin/tss…

supervisor 重启_supervisor_twiddler的使用

点击上方蓝字关注【 北邮郭大宝 】Supervisor可以很好的实现Python的进程管理,但是新增进程时需要配置文件,对于需要动态创建进程的场景不是很友好,supervisor_twiddler插件可以帮助实现上述功能。本文就supervisor_twiddler的使用做简单的de…

matlab的词云,Word Cloud (词云) - JavaScript

在上一篇中已经分享了用 Python 创建词云了。接下来继续总结其他创建词云的方法。&带道术用量确示常构端析以要效开的用,近不gt;> Create Word Cloud via JavaScrip要圈器是天的年编功小还久概据含直这请框结业未商屏页屏随会维气大机域页效实一应控高标tJav…

python数据分析的步骤排序_Python数据分析

一.数据分析步骤1.提出问题2.理解数据3.数据清洗4.构建模型5.数据可视化二.朝阳医院2018年销售数据数据导入在文件路径前加r(转义符)文件可能有多个sheet,所以用sheet_name重命名参数dtypestr同意先按照字符串读入,之后再转换salesDf.head(),…

archlinux php mysql,arch linux上安装 httpd+php+mysql+ openssl(转)

arch linux上安装 httpdphpmysql openssl(转)[more]在arch linux安装则是非常的容易,只要执行:# pacman -Sy apache php mysql openssl根据提示选择输入Y即可安装!1.修改apache配置文件默认的情况,apache是不支持PHP的&#xff0c…

ai人工智能python开发_Python才是人工智能AI的首选编程语言,你值得拥有……

在所有编程语言里,Python并不算萌新,从1991年发布第一个版本,至今已经快30年了。最近几年,随着人工智能概念的火爆,Python迅速升温,成为众多AI从业者的首选语言。根据数据平台 Kaggle发布的2017年机器学习及…

php bind_param,php – 在mysqli bind_param中绑定动态变量

当我尝试下面的代码时,它会给我一个警告mysqli_stmt::bind_param(): Number of elements in type definition string doesnt match number of bind variables$stmt $mysqli->prepare(SELECT * FROM users WHERE lname ? AND fname ?);$type "ss";$param ar…

unique函数_unique函数使用场景(一)

unique函数使用场景(一)前情提示:Microsoft 365(就是原来的office 365)已经推出有一段时间了,去年年审就在项目上使用365更新的一系列动态函数来提高审计效率(大胆一点,就是更好的偷懒)。讲解动态函数的文章不多,且365普及度低&am…

php属性未定义,PHP-警告-未定义的属性:stdClass-修复?

我在错误日志中收到此警告,并想知道如何在代码中更正此问题。警告:PHP注意:未定义属性:stdClass :: $ records在440行的script.php中一些代码:// Parse object to get account ids// The response doesnt have the rec…

python做数据和大数据区别_不懂Python,不懂大数据的人,和咸鱼有什么区别?

原标题:不懂Python,不懂大数据的人,和咸鱼有什么区别?在这个处处充斥着大数据影响的时代之下,不懂Python,不懂大数据,你就可能轻易地错过身边的黄金。我们生活在数据密布的环境中,就…

c++gdal如何在大图像中截取小图像并获取其图像信息_【图像处理】OpenCV系列十 --- 边缘检测之Canny算子...

上一篇我们学习了图像处理形态学相关知识点,相信大家学习之后已经对形态学有了足够的理解了,那么接下来,我们一起来学习一下图像处理中的边缘检测吧!我们将会重点学习边缘检测各种算子和滤波器 --- Canny算子,Sobel算子,Laplace算…

php登录信息首页显示,首页登录后怎么在首页显示用户名以及隐藏登录框?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼index.php:登录页面用户名:密码:没有账号?立即注册——————————————————————————doaction.php:header("Content-type:text/html;charsetutf…

python矩阵相乘例题_百道Python入门级练习题(新手友好)第一回合——矩阵乘法...

题目描述【问题描述】编写程序,完成3*4矩阵和4*3整数矩阵的乘法,输出结果矩阵。【输入形式】一行,供24个整数。以先行后列顺序输入第一个矩阵,而后输入第二个矩阵。【输出形式】先行后列顺序输出结果矩阵&a…

笔记本屏幕30hz_你真的了解笔记本电池和电源适配器吗?

很多笔记本硬件配置相似,但续航或性能却相差一大截。实际上,笔记本的续航能力在很大程度上取决于电池;而实际性能,则还会受到电源适配器功率的影响。想认识这两个硬件,就需要从它们的基本参数谈起。笔记本电池笔记本的…

java 俄文,俄文字体在word里面是什么

在Word里输入俄语字母,一打字字体就变成宋体了,俄语字母间间距...我不知道你这个俄语输入法补丁的字库用的是什么,如果是汉字库里好像就没办法调了,试一下把字体改成西文的Times New Roman、Arial等字体看有没有变化,如果没有,那就…

excel公式不自动计算_【纯干货】值得收藏的Excel日期计算公式!

点击上面“零壹快学”关注我们小伙伴们好,今天零壹学长给大家整理了一些常用的日期计算公式,赶紧往下看吧!01根据身份证号计算出生年月--TEXT(MID(A2,7,8),"0-00-00")02根据身份证号提取性别IF(MOD(MID(A2,15,3),2),"男"…