脚本编程

Python远程控制模块paramiko遇到的问题及解决记录

最近一直在开发自动化运维发布平台,底层命令行、文件通道主要基于paramiko模块,使用过程中遇到各种各样的问题,本文主要用于收集问题及解决记录,以备后续使用。 一、Error reading SSH protocol banner连接错误 这个关键词,在百度、谷歌一搜一大把的提问,也有少部分给出了解决方案,但是最终都无法解决,我经过不断尝试和解读paramiko源码,终于搞定了这个问题,在此记录分享下。 1、具体报错信息: 2、解决办法: 重新下载paramiko插件源码,解压后,编辑安装目录下的transport.py文件: vim build/lib/paramiko/transport.py   搜索 self.banner_timeout 关键词,并将其参数改大即可,比如改为300s: self.banner_timeout = 300 最后,重装paramiko即可。 3、下面的曲折、啰嗦的解决过程,不喜请跳过: 在谷歌搜到一个老外相关提问,虽然他说的是pysftp,其实也是基于paramiko: https://stackoverflow.com/questions/34288526/pysft-paramiko-grequests-error-reading-ssh-protocol-banner/44493465#44493465 他最后给出了他的解决方案: UPDATE: It seems the problem is caused by importing the package grequests. If I do not import grequests, pysftp works as expected. The issue was raised before but has not been solved 意思是,在paramiko使用前,先import grequests,就能解决问题。我照做之后,发现对手头的现网环境无效,可能错误产生的原因不一样。 但是,我从老外的问题描述过程中,找到了解决方法,他是这样说的: I have already tried changing the banner timeout from 15 seconds to 60 secs in the transport.py, but it did not solve the problem. 我看到有个timeout和transport.py,就想到现网那些报Error reading SSH protocol banner错误的机器也是非常卡,而且目测了下发起paramiko连接到报错的时间,基本是相同的。 于是系统中搜索,并找到了transport.py这个文件: /usr/lib/python2.7/site-packages/paramiko/transport.py 并搜了下banner,发现果然有一个参数设置,而且和目测的超时基本一致! 于是,顺手修改成300S,并重新测试发现没任何效果,依然15S超时。接着打断点、甚至移走这个文件,问题依旧!!看来这个文件不会被引用。。。 回到最初的报错信息,发现里面显示的是: 而系统里面搜不到这个问题,最后醍醐灌顶,发觉Python模块编译后,基本是以egg文件保存的,看来 必须修改源码才行了。 于是cd到paramiko的源码目录,执行搜索,找到2各transport.py文件: 尝试将文件中的 self.banner_timeout 值改成300,重新安装paramiko,结果一次性测试成功! 然后,我顺便在老外的帖子回答了下(请忽略蹩脚的英语),算是回馈吧! 二、paramiko远程执行后台脚本“阻塞”问题 我写的远程命令通道上线之后,发现在远程脚本中后台再执行另一个脚本,通道会一直等待后台脚本执行完成才会返回,有时甚至会僵死。...
阅读全文
脚本编程

分享一个入门级可控多线程shell脚本方案

说到shell可控多线程,网上分享的大部分是管道控制的方案。这种方案,张戈博客也曾经实战并分享过一次:《Shell+Curl网站健康状态检查脚本,抓出中国博客联盟失联站点》,感兴趣的朋友可以看看。 下面张戈博客再分享另一种更容易理解的入门级可控多线程shell脚本方案:任务切割、各个击破。 先来 1 段场景描述: 某日,在鹅厂接到了这个任务,需要在Linux服务器中,对几千个IP进行一次Ping检测,只要取得ping可达的IP就好。如果单个IP去ping测试,虽然也可以完成任务,几千个IP还好了,如果更多呢? 鉴于这个case简单程度,第一时间先放弃了以前用过的管道方案,而是采用了各个击破的思想。 简单思路: 按照任务切割的“战略思想”,我先将这几千IP存入一个iplist文件,然后写一个分割函数,将这个文件分成多份临时IP清单,最后,用多线程遍历这些临时IP文件即可变相实现多线程了。 具体代码: 将代码保存为ping.sh之后,执行  sh ping.sh  iplist 100 的过程如下: 先将iplist切割成100份,存放在 SplitFile 文件夹中 然后,通过for循环读取这些分割文件,并在后台使用while循环对其中ip执行ping命令。 由于while是丢后台的, 所以for循环会一次性执行100个while,相当于开启了100个线程,速度自然不可同日而语矣。 其中,切割的份数即你想要开启的多线程数量,很明显,这种任务分割的思路虽然没有管道方案来的高大上,但是其思想更加简单易懂,而且通用性也更好,适合入门级的简单多线程任务。
阅读全文
操作系统

解决dos2unix/unix2dos报错,并在家目录下生成u2dtmp*文件问题

最近接到一个 case:大数据分析那边反馈我们这边推送的数据同比去年同期少了很多。这是很不正常的,因为业务一直在增长。 于是,我开始顺藤摸瓜的跟进。一开始就发现一个小问题:scp 推送文件脚本执行后居然会报错: # sh pushdata.sh dos2unix: converting file pushdata.log to UNIX format ... dos2unix: problems renaming './u2dtmp8jwsge' to 'pushdata.log' output file remains in './u2dtmp8jwsge' dos2unix: problems converting file pushdata.log 原来是将生成的日志转换成Unix格式。按理说应该不会影响数据的推送,不过还是顺手处理下。 奇怪的是,人工去执行 dos2unix 却是正常的,看来和脚本有关系了。看了半天的脚本,也没看出哪儿有明显的错误: dos2unix  /data/pushdata.log 还是先不浪费时间自己摸索了,直接丢百度一下,发现并没有什么luan用。进而丢谷歌,终于在一个国外论坛找到了正确的解释: It turns out that when you run the script from cron your current directory (PWD) is set to your home directory. Unix2dos creates the temporary file used in the conversion in your home directory then can't find it to rename it. Not sure why it can't find it. I added a change directory command (cd) and Unix2dos worked. 大概意思是,crontab 计划任务中的脚本当前执行路径默认会设置为家目录。所以,dos2unix/unix2dos 会在家目录下创建转换后的临时文件(u2dtmp****),导致命令无法在目标路径找到将临时文件,并重命名为被处理的文件名,作者表示他也不知道为什么会找不到。不过他给出的解决办法就是:在脚本里面加入cd到日志所在路径的命令即可。 比如,本文case中可以在脚本一开始处加入...
阅读全文
操作系统

Linux在批量服务器管理中实用的PS1命令提示符格式

作为一个大公司的运维,手头管理了成百上千的服务器是家常便饭,甚至更多。而我们一般都是用跳板机登陆,由于这些机器一般都是克隆或者虚拟化出来的,所以登陆后的命令行提示符几乎是一个模子刻出来的,比如都是:# 这时,我们肯定会经常遇到这样一个困扰:操作服务器时因某事中断,回头继续操作的时候肯定会ifconfg确认下是否是我要操作的服务器,因为无法从表象识别。 所以,我们很有必要将这个PS1命令行提示符优化一下。每个运维攻城狮肯定都有自己的习惯,不过我还是推荐一个服务器批量管理中比较使用的PS1格式吧! PS1是神马?PS1是linux里头的一个默认的环境变量,至于当前系统的PS1是如何设置的,你可以使用命令“env|grep PS1”来查看 。 其实PS1就是用来设置命令提示符格式的环境变量。 下面贴一下PS1的配置参数: 当然,为了更好的识别,我们还可以加入一些颜色设置,这个就不赘述了,百度一下shell颜色即可,当然记得参考下文的PS1进行自定义。 为了更好的区分服务器,我建议使用如下格式: 所以PS1可以如下设置: 但是机器太多,这个IP总不能每次手动修改,所以还是写个脚本来修改吧!(当然,你也可以先获取IP,赋值变量加入到PS1) 脚本很简单: 好了,最后直接 source ./update_PS1.sh 即可看到效果: 重新登陆或source /etc/profile,就可以看到效果了: 这样设置之后,就能清晰的知道现在操作的是服务器是哪一台,而不至于混淆。
阅读全文
脚本编程

Linux下的mongodb服务脚本,以备不时之需

前些天,一位开发同事找到我,说他测试环境的 mongodb 经常挂掉,要我写一个监控或复活的脚本。我觉得很奇怪,测试环境又没啥负载,经常挂掉肯定有非常规原因。 跑过去看了一下日志,发现存在stop记录,我就纳闷了,没人操作他还会自己stop。这明显不是挂掉了,于是到history中看了下同事的启动命令: 原来如此!因为他没有用nohup启动,所以只要他的终端离线或者关闭,mongodb就会自动退出了!解决办法很简单,如下启动即可: 这样敲命令也着实苦逼,所以从网上找了一个mongodb服务脚本就舒服多了: 将代码保存到 /etc/init.d/mongodb,然后使用 chmod +x /etc/init.d/mongodb 添加执行权限。 现在,就可以使用 service 命令来控制mongodb了: 非常简单,贴到博客记录一下,以备不时之需。
阅读全文
脚本编程

SEO技巧:Shell脚本自动提交网站404死链到搜索引擎

最近在折腾博客主题,通常来说大多数人认为换主题会影响SEO,实际上只要你把工作都做到位了,是没有任何问题的。比如,换主题后你得仔细检查标题和描述等内容是否发生改变、换主题后是否带来了大量的404页面等。当然,更细微的可能是换主题之后,网站的内链网络也发生了微妙的改变,但是整体的影响较小。 总之,张戈博客这次更换主题基本上没有看到明显的SEO影响,反而出现几个新的关键词。好了,题外话到此结束,下面分享一下从Nginx日志分析并生成能提交到搜索引擎的死链文件的Shell脚本。 一、前因后果 今天在看百度站长平台的抓取频次的时候,发现最近抓取次数有所下滑,并且平均响应时间也有所上升,感觉和最近频繁折腾主题以及访问量增加有所关系: 这个问题倒是好解决,等主题稳定了,页面静态缓存文件也就不会频繁被手工删除,整个网站的抓取响应时间应该就能回到正常水平。 再往下看,却发现网站抓取中出现的404数据也呈上升趋势: 实际上,张戈博客以前是手动提交过死链文件的,但后来没时间也就没去搭理更新了。看来这个工作还得重新做起来,并且实现自动化才行了。 二、Shell脚本 说做就做,简单的写了个 Shell 脚本就搞定了! 脚本名称:网站死链生成脚本 脚本功能:每天定时分析网站前一天的 nginx 日志, 然后提取状态码为404并且UA为百度蜘蛛的抓取路径,并写入到网站根目录下的 death.txt 文件,用于提交百度死链。 脚本代码: 使用说明: ①、脚本适用于每天都做了日志切割的Nginx,没有做的朋友可以参考博客之前的文章: nginx日志切割及7天前的历史日志删除脚本 ②、将代码保存为 shell 脚本,比如 deathlink.sh,然后如下建立任务计划: ③、执行后,将在网站根目录生成死链文件:death.txt,可以浏览器访问看看内容,比如: https://zhang.ge/death.txt ④、前往立即前往提交这个死链文件即可: 这样一来,系统会每天执行脚本,将昨天的百度蜘蛛爬到的404路径保存到网站根目录下的 death.txt,以备百度死链抓取工具前来抓取。 效果截图: 下面贴上这几天死链抓取(百度定时抓取,无需人工干预)及处理情况,效果还是非常明显的: 值得说明的是,这些死链记录是累加的,已保存的死链数据,就算百度蜘蛛不爬了也会继续保存,需要人工清理,不过一般不清理也没啥问题。 注意事项: ①、如果你的 nginx服务 并没有配置相应的 access 日志,请自行在 server 下添加所需网站的 access 日志,否则脚本无法使用; ②、脚本适用的access日志格式如下:   如果和你的不一样,则需要修改脚本中的awk指定的域(即$9、$15以及$7)。 三、其他拓展 ①、如果你之前没有做过 Nginx 日志切割,那么可以直接用下面这个脚本来一次性搞定: ②、其他WEB服务器,比如 Apache 或 IIS,只要参考脚本思路,修改成实际的路径或日志字段,同样可以写一个相同功能的 Shell 或 Batch 脚本,有需求的朋友自己去研究折腾吧! 好了,本文暂时就分享这么多,希望对你有所帮助!
阅读全文