转载于运维笔记

Categories: Shell

也许很多人认为shell不能并发任务,其实可通过其它一些方式来实现。下面的脚本是我批量快速管理500+服务器脚本,阅读该脚本前建议先看《自动执行远程主机命令expect脚本》、《自动远程拷贝expect脚本》和《getopt:命令行选项、参数处理》

用法:

Usage: ./multi_main.sh [-h|--help][-v|-V|--version][-l|--iplist ... ][-c|--config ... ][-t|--sshtimeout ... ][-T|--fttimeout ... ][-L|--bwlimit ... ][-n|--ignore]

cat config.txt #上传文件和执行命令

file:::~/scripts/test.sh /root/ push
com:::./test.sh

cat iplist.txt  #ip列表

# Usage:
#ip port user password [password_2] [password_3] [password_4]
# Example:
#192.168.0.100 22 root 123456
192.168.0.200 22 root 123456
192.168.0.201 22 root 123456
...
./multi_main.sh -c config.txt -l iplist.txt #开始执行,可查看result目录下的日志来分析是否执行成功

脚本如下:

  1. mssh.exp 执行远程服务器命令expect脚本
  2. mscp.exp 向远程服务器上传或下载文件expect脚本(rsync)
  3. thread.sh 向一台服务器发起动作
  4. ckssh.py 检查ssh是否通
  5. multi_main.sh 批量执行,对每台调用thread.sh

mssh.exp:

#!/usr/bin/expect --if { [llength $argv] < 4 } {puts "Usage: $argv0 ip user passwd port commands timeout"exit 1
}match_max 600000set ipcode [lindex $argv 0]
set ip [exec dc -e $ipcode]
set user [lindex $argv 1]
set passwdcode [lindex $argv 2]
set passwd [exec dc -e $passwdcode]
set portcode [lindex $argv 3]
set port [exec dc -e $portcode]
set commands [lindex $argv 4]
set timeoutflag [lindex $argv 5]set yesnoflag 0
set timeout $timeoutflagfor {} {1} {} {
# for is only used to retry when "Interrupted system call" occuredspawn /usr/bin/ssh -o GSSAPIAuthentication=no -q -l$user -p$port $ipexpect  {"assword:" {send "$passwd\r"break;}"yes/no)?" {set yesnoflag 1send "yes\r"break;}"FATAL" {puts "\nCONNECTERROR: $ip occur FATAL ERROR!!!\n"exit 1}timeout {puts "\nCONNECTERROR: $ip Logon timeout!!!\n"exit 1}"No route to host" {puts "\nCONNECTERROR: $ip No route to host!!!\n"exit 1}"Connection Refused" {puts "\nCONNECTERROR: $ip Connection Refused!!!\n"exit 1}"Connection refused" {puts "\nCONNECTERROR: $ip Connection Refused!!!\n"exit 1}"Host key verification failed" {puts "\nCONNECTERROR: $ip Host key verification failed!!!\n"exit 1}"Illegal host key" {puts "\nCONNECTERROR: $ip Illegal host key!!!\n"exit 1}"Connection Timed Out" {puts "\nCONNECTERROR: $ip Logon timeout!!!\n"exit 1}"Interrupted system call" {puts "\n$ip Interrupted system call!!!\n"}
}
}if { $yesnoflag == 1 } {expect {"assword:" {send "$passwd\r"}"yes/no)?" {set yesnoflag 2send "yes\r"}}
}if { $yesnoflag == 2 } {expect {"assword:" {send "$passwd\r"}}
}expect {"]" {send "$commands \r"}"assword:" {send "$passwd\r"puts "\nPASSWORDERROR: $ip Password error!!!\n"exit 1}
}expect {"]" {send "sleep 1 \r"}
}expect {"]" {send "exit\r"}
}expect eof {puts "OK_SSH: $ip\n"exit 0;
}

mscp.exp:

#!/usr/bin/expect --proc Usage_Exit {self} {puts ""puts "Usage: $self ip user passwd port sourcefile destdir direction bwlimit timeout"puts ""puts "       sourcefile: a file or directory to be transferred"puts "                   需要拷贝目录时目录名后不要带 /, 否则会拷贝该目录下的所有文件"puts "       destdir:    the location that the sourcefile to be put into"puts "       direction:  pull or push"puts "                   pull: remote -> local"puts "                   push: local -> remote"puts "       bwlimit:    bandwidth limit, kbit/s, 0 means no limit"puts "       timeout:    timeout of expect, s, -1 means no timeout"puts ""exit 1
}if { [llength $argv] < 9 } {Usage_Exit $argv0
}set ipcode [lindex $argv 0]
set ip [exec dc -e $ipcode]
set user [lindex $argv 1]
set passwduncode [lindex $argv 2]
set passwd [exec dc -e $passwduncode]
set portcode [lindex $argv 3]
set port [exec dc -e $portcode]
set sourcefile [lindex $argv 4]
set destdir [lindex $argv 5]
set direction [lindex $argv 6]
set bwlimit [lindex $argv 7]
set timeoutflag [lindex $argv 8]set yesnoflag 0
set timeout $timeoutflagfor {} {1} {} {
# for is only used to retry when "Interrupted system call" occuredif { $direction == "pull" } {if { $bwlimit > 0 } {spawn rsync -crazP --bwlimit=$bwlimit -e "/usr/bin/ssh -o GSSAPIAuthentication=no -q -l$user -p$port" $ip:$sourcefile $destdir} elseif { $bwlimit == 0 } {spawn rsync -crazP -e "/usr/bin/ssh -o GSSAPIAuthentication=no -q -l$user -p$port" $ip:$sourcefile $destdir} else {Usage_Exit $argv0}} elseif { $direction == "push" } {if { $bwlimit > 0 } {spawn rsync -crazP --bwlimit=$bwlimit -e "/usr/bin/ssh -o GSSAPIAuthentication=no -q -l$user -p$port" $sourcefile $ip:$destdir} elseif { $bwlimit == 0 } {spawn rsync -crazP -e "/usr/bin/ssh -o GSSAPIAuthentication=no -q -l$user -p$port" $sourcefile $ip:$destdir} else {Usage_Exit $argv0}} else {Usage_Exit $argv0
}expect  {"assword:" {send "$passwd\r"break;}"yes/no)?" {set yesnoflag 1send "yes\r"break;}"FATAL" {puts "\nCONNECTERROR: $ip occur FATAL ERROR!!!\n"exit 1}timeout {puts "\nCONNECTERROR: $ip Logon timeout!!!\n"exit 1}"No route to host" {puts "\nCONNECTERROR: $ip No route to host!!!\n"exit 1}"Connection Refused" {puts "\nCONNECTERROR: $ip Connection Refused!!!\n"exit 1}"Connection refused" {puts "\nCONNECTERROR: $ip Connection Refused!!!\n"exit 1}"Host key verification failed" {puts "\nCONNECTERROR: $ip Host key verification failed!!!\n"exit 1}"Illegal host key" {puts "\nCONNECTERROR: $ip Illegal host key!!!\n"exit 1}"Connection Timed Out" {puts "\nCONNECTERROR: $ip Logon timeout!!!\n"exit 1}"Interrupted system call" {puts "\n$ip Interrupted system call!!!\n"}
}}if { $yesnoflag == 1 } {expect {"assword:" {send "$passwd\r"}"yes/no)?" {set yesnoflag 2send "yes\r"}}
}if { $yesnoflag == 2 } {expect {"assword:" {send "$passwd\r"}}
}expect {"assword:" {send "$passwd\r"puts "\nPASSWORDERROR: $ip Password error!!!\n"exit 1}eof {puts "OK_SCP: $ip\n"exit 0;}
}

thread.sh:

#!/bin/bash# Default Parameters
myIFS=":::"     # 配置文件中的分隔符
TOOLDIR=~/scripts
cd $TOOLDIR#BEGINDATETIME=`date "+%F %T"`IP=$1P
PORT=$2P
USER=$3
PASSWD=$4P
CONFIG_FILE=$5                # 命令列表和文件传送配置列表,关键字为com:::和file:::
SSHTIMEOUT=$6                 # 远程命令执行相关操作的超时设定,单位为秒
SCPTIMEOUT=$7                 # 文件传送相关操作的超时设定,单位为秒
BWLIMIT=$8                    # 文件传送的带宽限速,单位为kbit/s# 针对一个$IP,执行配置文件中的一整套操作
while read eachline
do# 必须以com或file开头[ -z "`echo $eachline | grep -E '^com|^file'`" ] && continuemyKEYWORD=`echo $eachline | awk -F"$myIFS" '{ print $1 }'`myCONFIGLINE=`echo $eachline | awk -F"$myIFS" '{ print $2 }'`# 配置文件中有关键字file:::,就调用mscp.exp进行文件传送if [ "$myKEYWORD"x == "file"x ]; thenSOURCEFILE=`echo $myCONFIGLINE | awk '{ print $1 }'`DESTDIR=`echo $myCONFIGLINE | awk '{ print $2 }'`DIRECTION=`echo $myCONFIGLINE | awk '{ print $3 }'`$TOOLDIR/mscp.exp $IP $USER $PASSWD $PORT $SOURCEFILE $DESTDIR $DIRECTION $BWLIMIT $SCPTIMEOUT[ $? -ne 0 ] && echo -e "\033[31mSCP Try Out All Password Failed\033[0m\n"# 配置文件中有关键字com:::,就调用mssh.exp进行远程命令执行elif [ "$myKEYWORD"x == "com"x ]; then$TOOLDIR/mssh.exp $IP $USER $PASSWD $PORT "${myCONFIGLINE}" $SSHTIMEOUT#echo  $IP $USER $PASSWD $PORT "${myCONFIGLINE}" $SSHTIMEOUT[ $? -ne 0 ] && echo -e "\033[31mSSH Try Out All Password Failed\033[0m\n"elseecho "ERROR: configuration wrong! [$eachline] "echo "       where KEYWORD should not be [$myKEYWORD], but 'com' or 'file'"echo "       if you dont want to run it, you can comment it with '#'"echo ""exitfidone < $CONFIG_FILE#ENDDATETIME=`date "+%F %T"`#echo "$BEGINDATETIME -- $ENDDATETIME"
#echo "$0 $* --excutes over!"exit 0

ckssh.py:

#!/usr/bin/python
import socket,sys
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.settimeout(1)
try:sk.connect((sys.argv[1],int(sys.argv[2])))print 'ok'
except Exception:print 'no'
sk.close()

multi_main.sh:

#!/bin/bash
#Blog: blog.linuxeye.com######################  proc defination  ########################
# ignore rule
ignore_init()
{# ignore passwordarray_ignore_pwd_length=0if [ -f ./ignore_pwd ]; thenwhile read IGNORE_PWDdoarray_ignore_pwd[$array_ignore_pwd_length]=$IGNORE_PWDlet array_ignore_pwd_length=$array_ignore_pwd_length+1done < ./ignore_pwdfi# ignore ip addressarray_ignore_ip_length=0if [ -f ./ignore_ip ]; thenwhile read IGNORE_IPdoarray_ignore_ip[$array_ignore_ip_length]=$IGNORE_IPlet array_ignore_ip_length=$array_ignore_ip_length+1done < ./ignore_ipfi
}show_version()
{echo "version: 1.0"echo "updated date: 2014-05-28"
}show_usage()
{echo -e "`printf %-16s "Usage: $0"` [-h|--help]"echo -e "`printf %-16s ` [-v|-V|--version]"echo -e "`printf %-16s ` [-l|--iplist ... ]"echo -e "`printf %-16s ` [-c|--config ... ]"echo -e "`printf %-16s ` [-t|--sshtimeout ... ]"echo -e "`printf %-16s ` [-T|--fttimeout ... ]"echo -e "`printf %-16s ` [-L|--bwlimit ... ]"echo -e "`printf %-16s ` [-n|--ignore]"#echo "ignr_flag: 'ignr'-some ip will be ignored; otherwise-all ip will be handled"
}TOOLDIR=~/scripts
cd $TOOLDIRIPLIST="iplist.txt"                     # IP列表,格式为IP 端口 用户名 密码
CONFIG_FILE="config.txt"                # 命令列表和文件传送配置列表,关键字为com:::和file:::
IGNRFLAG="noignr"                       # 如果置为ignr,则脚本会进行忽略条件的判断
SSHTIMEOUT=100                          # 远程命令执行相关操作的超时设定,单位为秒
SCPTIMEOUT=2000                         # 文件传送相关操作的超时设定,单位为秒
BWLIMIT=1024000                         # 文件传送的带宽限速,单位为kbit/s
[ ! -d "result" ] && mkdir result# 入口参数分析
TEMP=`getopt -o hvVl:c:t:T:L:n --long help,version,iplist:,config:,sshtimeout:,fttimeout:,bwlimit:,ignore -- "$@" 2>/dev/null`[ $? != 0 ] && echo -e "\033[31mERROR: unknown argument! \033[0m\n" && show_usage && exit 1# 会将符合getopt参数规则的参数摆在前面,其他摆在后面,并在最后面添加--
eval set -- "$TEMP"while :
do[ -z "$1" ] && break;case "$1" in-h|--help)show_usage; exit 0;;-v|-V|--version)show_version; exit 0;;-l|--iplist)IPLIST=$2; shift 2;;-c|--config)CONFIG_FILE=$2; shift 2;;-t|--sshtimeout)SSHTIMEOUT=$2; shift 2;;-T|--fttimeout)SCPTIMEOUT=$2; shift 2;;-L|--bwlimit)BWLIMIT=$2; shift 2;;-n|--ignore)IGNRFLAG="ignr"; shift;;--)shift;;*)echo -e "\033[31mERROR: unknown argument! \033[0m\n" && show_usage && exit 1;;esac
done################  main  #######################
BEGINDATETIME=`date "+%F %T"`
[ ! -f $IPLIST ] && echo -e "\033[31mERROR: iplist \"$IPLIST\" not exists, please check! \033[0m\n" && exit 1[ ! -f $CONFIG_FILE ] && echo -e "\033[31mERROR: config \"$CONFIG_FILE\" not exists, please check! \033[0m\n" && exit 1IP_count=$(egrep -v '^#|^$' $IPLIST|wc -l)
IP_init=1
while [[ $IP_init -le $IP_count ]]
doegrep -v '^#|^$' $IPLIST | sed -n "$IP_init,$(expr $IP_init + 50)p" > $IPLIST.tmp #并发50IPSEQ=0while read IP PORT USER PASSWD PASSWD_2ND PASSWD_3RD PASSWD_4TH OTHERS# while read Linedo[ -z "`echo $IP | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|CNS'`" ] && continueif [ "`python $TOOLDIR/ckssh.py $IP $PORT`" == 'no' ];then[ ! -e ipnologin.txt ] && > ipnologin.txt[ -z "`grep $IP ipnologin.txt | grep $(date +%F)`" ] && echo "`date +%F_%H%M` $IP" >> ipnologin.txtcontinuefilet IPSEQ=$IPSEQ+1# 如果启用了忽略,则进入忽略流程if [ $IGNRFLAG == "ignr" ]; thenignore_initignored_flag=0i=0while [ $i -lt $array_ignore_pwd_length ]do[ ${PASSWD}x == ${array_ignore_pwd[$i]}x ] && ignored_flag=1 && breaklet i=$i+1done[ $ignored_flag -eq 1 ] && continuej=0while [ $j -lt $array_ignore_ip_length ]do[ ${IP}x == ${array_ignore_ip[$j]}x ] && ignored_flag=1 && breaklet j=$j+1done[ $ignored_flag -eq 1 ] && continuefi####### Try password from here #####for PW in $PASSWD $PASSWD_2ND $PASSWD_3RD $PASSWD_4TH#do#        PASSWD_USE=$PW#        $TOOLDIR/ssh.exp $IP $USER $PW $PORT true $SSHTIMEOUT#        [ $? -eq 0 ] && PASSWD_USE=$PW && break#donePASSWD_USE=$PASSWDIPcode=$(echo "ibase=16;$(echo "$IP" | xxd -ps -u)"|bc|tr -d '\\'|tr -d '\n')Portcode=$(echo "ibase=16;$(echo "$PORT" | xxd -ps -u)"|bc|tr -d '\\'|tr -d '\n')#USER=$USERPWcode=$(echo "ibase=16;$(echo "$PASSWD_USE" | xxd -ps -u)"|bc|tr -d '\\'|tr -d '\n')Othercode=$(echo "ibase=16;$(echo "$OTHERS" | xxd -ps -u)"|bc|tr -d '\\'|tr -d '\n')#echo $IPcode $Portcode $USER $PWcode $CONFIG_FILE $SSHTIMEOUT $SCPTIMEOUT $BWLIMIT $Othercode./thread.sh $IPcode $Portcode $USER $PWcode $CONFIG_FILE $SSHTIMEOUT $SCPTIMEOUT $BWLIMIT $Othercode | tee result/$IP.log &done < $IPLIST.tmpsleep 3IP_init=$(expr $IP_init + 50)
doneENDDATETIME=`date "+%F %T"`echo "$BEGINDATETIME -- $ENDDATETIME"
echo "$0 $* --excutes over!"exit 0

转载于:https://www.cnblogs.com/cheyunhua/p/8846949.html

并发批量管理500台以上服务器脚本分享(shell版)相关推荐

  1. 如何在20分钟内批量部署20台ESXi服务器?

    如何在20分钟内批量部署20台ESXi服务器? https://mp.weixin.qq.com/s?__biz=MjM5NTk0MTM1Mw==&mid=2650642256&idx ...

  2. 如何高效的管理1000台Windows服务器

    论运维人员如何高效的管理1000台Windows服务器 几年前运维工作量巨大,部门运维人员每天都需要管理上千台的服务器,并不定时的检查及处理不同服务器的问题,每次打开都要输入密码(WIN保存远程密码形 ...

  3. 用ClusterSSH管理多台Linux服务器(2)

    用ClusterSSH管理多台Linux服务器(2) 2011-03-21 15:45 黄永兵 译 51CTO.com 我要评论(0) 字号:T | T Cluster SSH 是一个可以用来通过SS ...

  4. 黑马超级远程桌面5.6(可以批量管理1000台VPS或微软mstsc连接的实用工具)

    目录 一.黑马超级远程桌面是什么? 二.使用介绍 三.官网下载 一.黑马超级远程桌面是什么? 它是一款可以批量管理1000台微软远程桌面连接的免费工具软件.可以代替手工输入密码等繁琐操作,节约你的时间 ...

  5. kvm最多能管几台服务器,高效管理500台服务器的kvm切换器配置方案

    数据中心的庞大,让所有的机房管理人员都是很头疼,如何让这些设备能跟高效的管理和运转起来呢?这就需要用到KVM来帮忙. 一.项目描述与需求分析: 某企业新建数据中心,计划采用KVM系统进行整合集中管控. ...

  6. shell实现批量在多台windows服务器上执行同一命令并获取返回结果

    1.    需求 在对windows服务器的运维当中,如果要查看当前的主机名.资源使用.软件安装情况等,大家是怎么操作呢,是登进去鼠标挨着点击查看,还是通过命令呢?貌似命令的方法比较专业一点.但是,如 ...

  7. 大型企业中如何批量管理千万台服务器之ansible自动化运维工具详解 [⭐建议收藏⭐]

    文章目录 ansible 自动化运维工具 详解 关于作者 作者介绍 一.ansible 概述 1.1 ansible 概述 1.2 是什么要使用 ansible 1.3 ansible 功能 1.4 ...

  8. PHP服务器脚本实例,Shell脚本实现的一个简易Web服务器例子分享_linux shell

    这篇文章主要介绍了Shell脚本实现的一个简易Web服务器例子分享,本文实现的Web服务器非常简单实用,可以在你不想安装nginx.apache等大型WEB服务器时使用,需要的朋友可以参考下 假设你想 ...

  9. 如何使用ansible管理多台远程服务器

    前置条件:假如需要使用服务器A控制服务器B(172.17.0.1).C(172.17.0.2).D(172.17.0.3). 一.安装&配置ansible 1.安装 yum install a ...

最新文章

  1. python英语翻译-python制作英语翻译小工具代码实例
  2. 邮件发送代码--网易服务器代理
  3. 测量仪图片_南昌高度仪价格,大行程非标影像测量仪组装
  4. java字符串底层实现_「JAVA」细述合理创建字符串,分析字符串的底层存储,你不该错过...
  5. 数据结构:(2)什么是数据结构
  6. 骨髓基质在正常和白血病个体中的细胞图谱|Cell最新(文末有彩蛋)
  7. maven服务器项目,Maven项目搭建
  8. HashSet底层存储元素的源码分析
  9. MATLAB电路仿真搭建教程
  10. 高级火山图 突出显示自定义的基因volcanic volcano plot duqiang 差异基因火山图
  11. 一句话详解常见的心理学效应
  12. rack puma rails
  13. zblog php wordpress,ZblogPHP转换WordPress教程
  14. python泊松分布_Python数据可视化:泊松分布详解
  15. GIF、SVG、PNG、图片格式转换
  16. java lang arithmetic_java.lang.ArithmeticException: Rounding necessary
  17. 计算器表格边框java_表格边框探秘
  18. 一个html基本写法,HTML5教程:HTML5的基础写法
  19. Druid.io系列(一):简介
  20. 无法斑驳的青春,折射出心里每一丝憧憬和每一缕不甘

热门文章

  1. 教师计算机培训考勤表,之江汇平台的使用-信息技术培训
  2. PCL滤波工具之StatisticalOutlierRemoval深度分析
  3. xilinx_Recovery/Removal
  4. Windows 防火墙的入站和出站规则说明
  5. 【Vue】 错误:Already included file name ‘××ב differs from file name ‘××ב only in casing的解决方法
  6. Java_JDK19.0.2_Ubuntu18.04中配合海康工业相机SDK环境搭建
  7. JSX语法学习(三)
  8. 教授建议:科研人员压力太大,应该培养一些吃喝玩乐之类“庸俗”的爱好
  9. 金蝶mysql_解决方案-金蝶财务软件中的数据库在哪里?
  10. 《数据结构》-第四章 串、数组和广义表(习题)