也许很多人认为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目录下的日志来分析是否执行成功
脚本如下:
- mssh.exp 执行远程服务器命令expect脚本
- mscp.exp 向远程服务器上传或下载文件expect脚本(rsync)
- thread.sh 向一台服务器发起动作
- 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 600000 set 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 $timeoutflag for {} {1} {} { # for is only used to retry when "Interrupted system call" occured spawn /usr/bin/ssh -o GSSAPIAuthentication=no -q -l$user -p$port $ip expect { "assword:" { send "$passwd\r" break; } "yes/no)?" { set yesnoflag 1 send "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" } }