Python实现ssh批量登录并执行命令


Posted in Python onOctober 25, 2016

局域网内有一百多台电脑,全部都是linux操作系统,所有电脑配置相同,系统完全相同(包括用户名和密码),ip地址是自动分配的。现在有个任务是在这些电脑上执行某些命令,者说进行某些操作,比如安装某些软件,拷贝某些文件,批量关机等。如果一台一台得手工去操作,费时又费力,如果要进行多个操作就更麻烦啦。

或许你会想到网络同传,网络同传是什么?就是在一台电脑上把电脑装好,配置好,然后利用某些软件,如“联想网络同传”把系统原样拷贝过去,在装系统时很有用,只要在一台电脑上装好,同传以后所有的电脑都装好操作系统了,很方便。同传要求所有电脑硬件完全相同,在联想的电脑上装的系统传到方正电脑上肯定会出问题的。传系统也是很费时间的,根据硬盘大小,如果30G硬盘,100多台电脑大约要传2个多小时,反正比一台一台地安装快!但是如果系统都传完了,发现忘了装一个软件,或者还需要做些小修改,再同传一次可以,但是太慢,传两次半天时间就没了。这时候我们可以利用ssh去控制每台电脑去执行某些命令。

先让我们回忆一下ssh远程登录的过程:首先执行命令 ssh username@192.168.1.x ,第一次登录的时候系统会提示我们是否要继续连接,我们要输入“yes”,然后等一段时间后系统提示我们输入密码,正确地输入密码之后我们就能登录到远程计算机,然后我们就能执行命令了。我们注意到这里面有两次人机交互,一次是输入‘yes',另一次是输入密码。就是因为有两次交互我们不能简单的用某些命令去完成我们的任务。我们可以考虑把人机交互变成自动交互,python的pexpect模块可以帮我们实现自动交互。下面这段代码是用pexpect实现自动交互登录并执行命令的函数:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
 
import pexpect 
 
def ssh_cmd(ip, passwd, cmd): 
  ret = -1 
  ssh = pexpect.spawn('ssh root@%s "%s"' % (ip, cmd)) 
  try: 
    i = ssh.expect(['password:', 'continue connecting (yes/no)?'], timeout=5) 
    if i == 0 : 
      ssh.sendline(passwd) 
    elif i == 1: 
      ssh.sendline('yes\n') 
      ssh.expect('password: ') 
      ssh.sendline(passwd) 
    ssh.sendline(cmd) 
    r = ssh.read() 
    print r 
    ret = 0 
  except pexpect.EOF: 
    print "EOF" 
    ssh.close() 
    ret = -1 
  except pexpect.TIMEOUT: 
    print "TIMEOUT" 
    ssh.close() 
    ret = -2  
  return ret

利用pexpect模块我们可以做很多事情,由于他提供了自动交互功能,因此我们可以实现ftp,telnet,ssh,scp等的自动登录,还是比较实用的。根据上面的代码相信读者已经知道怎么实现了(python就是那么简单!)。

用上面的代码去完成任务还是比较费时间的,因为程序要等待自动交互出现,另外ubuntu用ssh连接就是比较慢,要进行一系列的验证,这样才体现出ssh的安全。我们要提高效率,在最短的时间内完成。后来我发现了python里面的paramiko模块,用这个实现ssh登录更加简单。看下面的代码:

#-*- coding: utf-8 -*- 
#!/usr/bin/python  
import paramiko 
import threading 
def ssh2(ip,username,passwd,cmd): 
  try: 
    ssh = paramiko.SSHClient() 
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
    ssh.connect(ip,22,username,passwd,timeout=5) 
    for m in cmd: 
      stdin, stdout, stderr = ssh.exec_command(m) 
#      stdin.write("Y")  #简单交互,输入 ‘Y'  
      out = stdout.readlines() 
      #屏幕输出 
      for o in out: 
        print o, 
    print '%s\tOK\n'%(ip) 
    ssh.close() 
  except : 
    print '%s\tError\n'%(ip) 
if __name__=='__main__': 
  cmd = ['cal','echo hello!']#你要执行的命令列表 
  username = "" #用户名 
  passwd = ""  #密码 
  threads = []  #多线程 
  print "Begin......" 
  for i in range(1,254): 
    ip = '192.168.1.'+str(i) 
    a=threading.Thread(target=ssh2,args=(ip,username,passwd,cmd))  
    a.start()

上面的程序还是有些技巧的:

  • 利用多线程,同时发出登录请求,同时去连接电脑,这样速度快很多,我试了一下,如果不用多线程,直接一个一个挨着执行的话,大约5~10秒钟才能对一台电脑操作完,具体时间要根据命令的来决定,如果是软件安装或者卸载时间要更长一些。这样下来怎么也要一二十分钟,用多线程后就快多了,所有的命令执行完用了不到2分钟!
  • 最好用root用户登录,因为安装或者卸载软件的时候如果用普通用户又会提示输入密码,这样又多了一次交互,处理起来就比较麻烦!安装软件时apt-get install xxx 最好加上“-y”参数,因为有时安装或删除软件时提示是否继续安装或卸载,这又是一次自动交互!加上那个参数后就没有人机交互了。
  • 循环时循环所有ip,因为计算机的ip是路由器自动分配的,保险起见,最好全部都执行,保证没有遗漏的主机
  • 远端执行命令时如果有交互,可以这样用 stdin.write("Y")来完成交互,“Y”就是输入“Y”。
  • 把所有的命令放到一个列表里面,遍历列表可以依次执行列表里面的命令
  • 为了更好的进行控制,最好在电脑上提前把root用户打开,装好ssh服务器并让其开机自动执行。

希望本文所述对你有所帮助,Python实现ssh批量登录并执行命令内容就给大家介绍到这里了。希望大家继续关注我们的网站!想要学习Python可以继续关注本站。

Python 相关文章推荐
Python使用os模块和fileinput模块来操作文件目录
Jan 19 Python
Python字符串拼接、截取及替换方法总结分析
Apr 13 Python
Python3 适合初学者学习的银行账户登录系统实例
Aug 08 Python
人机交互程序 python实现人机对话
Nov 14 Python
Python使用pickle模块报错EOFError Ran out of input的解决方法
Aug 16 Python
python 在指定范围内随机生成不重复的n个数实例
Jan 28 Python
Pycharm 文件更改目录后,执行路径未更新的解决方法
Jul 19 Python
Python lambda表达式filter、map、reduce函数用法解析
Sep 11 Python
AUC计算方法与Python实现代码
Feb 28 Python
Pyinstaller加密打包应用的示例代码
Jun 11 Python
解决Keras 自定义层时遇到版本的问题
Jun 16 Python
Python gevent协程切换实现详解
Sep 14 Python
详解Python的Lambda函数与排序
Oct 25 #Python
Python脚本实现Web漏洞扫描工具
Oct 25 #Python
python+django快速实现文件上传
Oct 24 #Python
python实现简单爬虫功能的示例
Oct 24 #Python
简单谈谈Python中的反转字符串问题
Oct 24 #Python
Python 内置函数complex详解
Oct 23 #Python
Python检测生僻字的实现方法
Oct 23 #Python
You might like
基于AppServ,XAMPP,WAMP配置php.ini去掉警告信息(NOTICE)的方法详解
2013/05/07 PHP
基于session_unset与session_destroy的区别详解
2013/06/03 PHP
destoon出现验证码不显示时的紧急处理方法
2014/08/22 PHP
php使用变量动态创建类的对象用法示例
2017/02/06 PHP
PDO::getAvailableDrivers讲解
2019/01/28 PHP
js之WEB开发调试利器:Firebug 下载
2007/01/13 Javascript
IE中createElement需要注意的一个问题
2010/07/13 Javascript
ExtJs中简单的登录界面制作方法
2010/08/19 Javascript
浅说js变量
2011/05/25 Javascript
网页加载时页面显示进度条加载完成之后显示网页内容
2012/12/23 Javascript
详解JavaScript数组的操作大全
2015/10/19 Javascript
jQuery图片轮播插件——前端开发必看
2016/05/31 Javascript
jQuery 3.0 的 setter和getter 模式详解
2016/07/11 Javascript
详解JS中的快速排序与冒泡
2017/01/10 Javascript
angular 动态组件类型详解(四种组件类型)
2017/02/22 Javascript
Vue学习笔记进阶篇之过渡状态详解
2017/07/14 Javascript
jQuery实现的鼠标滚轮控制图片缩放功能实例
2017/10/14 jQuery
使用ionic(选项卡栏tab) icon(图标) ionic上拉菜单(ActionSheet) 实现通讯录界面切换实例代码
2017/10/20 Javascript
利用React Router4实现的服务端直出渲染(SSR)
2019/01/07 Javascript
关于vue状态过渡transition不起作用的原因解决
2019/04/09 Javascript
js实现拖动缓动效果
2020/01/13 Javascript
vue中重定向redirect:‘/index‘,不显示问题、跳转出错的完美解决
2020/09/28 Javascript
[01:10]3.19DOTA2发布会 三代刀塔人第一代
2014/03/25 DOTA
python selenium 查找隐藏元素 自动播放视频功能
2019/07/24 Python
python 密码学示例——凯撒密码的实现
2020/09/21 Python
Python定时任务框架APScheduler原理及常用代码
2020/10/05 Python
CSS3 Backgrounds属性相关介绍
2011/05/11 HTML / CSS
澳大利亚香水在线:Price Rite Mart
2017/12/28 全球购物
T3官网:头发造型工具
2019/12/26 全球购物
网络信息管理员岗位职责
2014/01/05 职场文书
高三语文教学反思
2014/01/15 职场文书
酒后驾驶检讨书
2014/01/27 职场文书
初级党校心得体会
2014/09/11 职场文书
实习单位推荐信
2015/03/27 职场文书
redis 限制内存使用大小的实现
2021/05/08 Redis
python人工智能human learn绘图可创建机器学习模型
2021/11/23 Python