zoukankan      html  css  js  c++  java
  • Linux shell 脚本批量登录机器执行命令

    0x00:场景:

      服务器管理员,管理的机器是几十、几百、几千数量级别的,

      当某些情况下,只能登录ssh命令行去执行命令时,难道要手工?当然不是,肯定是要脚本自己去登录执行命令。

    0x01:脚本需要用到expect命令,安装方法

    # yum -y install expect
    

      

    0x02:执行命令脚本,auto_search_file.sh

    #!/bin/bash
    ## file name : auto_search_file.sh
    
    ## 判断输入参数个数为0,提示并退出
    if [ $# -eq 0  ];then
            echo -e "\nUsage: \n\t sh $0 command\n"
            exit
    fi
    ## 判断 ip_lists.txt 文件是否存在,不存在提示并退出
    if [ ! -e ip_lists.txt  ];then
            echo -e "\nError:  Not \"ip_lists.txt\" file\n"
            exit
    fi
    
    ## 以下, ip_lists_completes.txt和ip_lists_black.txt任一文件内容为空
    ## 则ip_lists_temp.txt文件也为空
    ## 插入内容随意,但最好是IP格式,防止奇怪问题
    ## 写127.0.0.1和127.0.0.2只是区分在什么状态下执行的
    
    ##判断ip_lists_completes.txt文件是否存在,不存在则创建
    if [ -e ip_lists_completes.txt ];then
            ## 文件存在,且内容为空则插入内容127.0.0.2
            count_comple=`wc -l ip_lists_completes.txt|awk '{print $1}'`
            if [ ${count_comple} -eq 0 ];then 
                    echo "127.0.0.2" >ip_lists_completes.txt
            fi
    else
            ##文件不存在则创建,并插入内容127.0.0.1
            echo "127.0.0.1" >ip_lists_completes.txt
    fi
    ##判断ip_lists_black.txt文件是否存在,不存在则创建
    if [ -e ip_lists_black.txt ];then
            ## 文件存在,且内容为空则插入内容127.0.0.2
            count_black=`wc -l ip_lists_black.txt|awk '{print $1}'`
            if [ ${count_black} -eq 0 ];then 
                    echo "127.0.0.2" >ip_lists_black.txt
            fi
    else
            ##文件不存在则创建,并插入内容127.0.0.1
            echo "127.0.0.1" >ip_lists_black.txt
    fi
    
    ## 传入要执行的命令
    sh_cmd=$1
    ## 过滤ip_lists_black.txt黑名单里IP和ip_lists_completes.txt已经执行过的IP
    ## 未执行的IP放到ip_lists_temp.txt
    cat ip_lists.txt |grep -v "`cat ip_lists_black.txt`" |grep -v "`cat ip_lists_completes.txt`" > ip_lists_temp.txt
    ## 将多行,合并成一行,用空格分隔
    ip_lists=`cat ip_lists_temp.txt | tr "\n" " "`
    
    ## 遍历IP列表并执行命令
    for ip_list in ${ip_lists}
    do
            ## 提示
    	echo -e "\n---------- Currect_IP=${ip_list} -----------------"
    	echo "Currect_IP=${ip_list}"
            ## 获取密码列表里的密码,tail -1 要最后一个,是最新的密码
    	ip_passwd=`grep ${ip_list} /home/test/get_password/pwd_history.txt |tail -1 | awk -F ":" '{print $2}'`
            ## 如过密码为空,则调用get_password.sh文件匹配密码
    	if [ -z ${ip_passwd} ];then
    		echo "Currect_IP=${ip_list} Password is NULL."
    		cd /home/zxl/auto_get_password/
                    ## 传入当前IP匹配密码
    		sh auto_get_password.sh ${ip_list}
                    ## 等待1秒,让缓存写入文件
    		sleep 1
                    ## 回到原目录
    		cd -
                    ## 再次获取密码
    		ip_passwd=`grep ${ip_list} /home/test/get_password/pwd_history.txt |tail -1 | awk -F ":" '{print $2}'`
    	fi
    	
    	echo ""
            ## 给expect传入IP 、密码来执行命令。 记录日志tee -a $0.log,$0当前脚本的名字
    	expect auto_search_file.exp ${ip_list} ${ip_passwd} "${sh_cmd}" | tee -a $0.log
    	## search completes ip to file
    	## 记录执行完成的IP,防止脚本异常退出,下次启动重头开始执行
    	echo "${ip_list}" >> ip_lists_completes.txt 
    done
    
    ## 全部执行完成,则删除ip_lists_completes.txt文件
    echo "[ info ] rm ip_lists_completes.txt"
    \rm ip_lists_completes.txt
    ## 提示,执行命令完成
    echo "[ OK ]  Exec command done"
     
    

      *注:auto_get_password.sh如何匹配密码,查看另一篇文章https://www.cnblogs.com/wutou/p/15738391.html

     0x03:执行命令expect脚本auto_search_file.exp

    #!/usr/bin/expect
    ## file name : auto_search_file.exp
    
    ## 检查传入参数不等于3个,提示并退出
    if { $argc != 3 } {
    	#send_user "Usage: expect $argv0 IP Passwd cmd"
    	puts "\nUsage: \n\texpect $argv0 IP Passwd cmd\n"
    	exit
    }
    
    ## 传入3个参数赋值
    set ip [lindex $argv 0]
    set passwd [lindex $argv 1]
    set cmd [lindex $argv 2]
    
    ## 用root用户执行cmd变量里命令
    spawn ssh root@$ip "$cmd"
    expect {
    	## 提示信息里有yes/no 发送yes
    	"yes/no"	{send "yes\r";exp_continue}
    	## 提示信息里有password 发送密码
    	"*password*"	{send "$passwd\r"}
    }
    send_user "\n"
    expect eof
    send_user "\n"
    

      

    0x04: 远程调用

       因为某些原因,本地执行脚本访问IP会有限制,比如“安全人员”只允许员工机器登录很少的IP网段,但是服务可以访问所有网段。  

      我们可把get_password.sh文件放到服务的某个路径下,我们从本地传参给服务器调用。

      这里我们把上面的get_password.sh脚本,放到服务器上test用户的"家"目录下,绝对路径/home/test/auto_search_file/auto_search_file.sh

    文件名:l_auto_search_file.sh

    #!/bin/bash
    ## file name : l_auto_search_file.sh
    expect 50_auto_search_file.exp "$1" | tee -a $0.log
    

    文件名:50_auto_search_file.exp (因为IP里带50,所以文件名前面加了50好区分)

    #!/usr/bin/expect
    ## file name : 50_auto_search_file.exp
    
    ## 获取传入的参数
    set cmd  [lindex $argv 0]
    set cmd_temp "cd auto_search_file && sh auto_search_file.sh '$cmd'" 
    set password "test123"
    
    ## 用ssh方式登录,并执行cmd_temp里命令
    ## expect语法里,要执行的命令必须要能够“”括起来,比如"$cmd_temp"
    spawn ssh test@192.168.1.50 "$cmd_temp" 
    expect "*password" {send "$password\n"}
    expect eof
    

      

    0x05:使用

    本地使用:

    # sh auto_search_file.sh "ls -l"

    远程调用:

    # sh l_auto_search_file.sh "ls -l"

    -

  • 相关阅读:
    按钮在点击的时候,怎么取消按钮中的文本被选中
    JS观察者模式-自定义事件
    DIV中文字换行显示
    JS、CSS中的相对路径
    监听窗口大小改变,同时根据窗口大小修改某个元素的大小
    jquery中点击切换的实现
    lua_自己对“lua函数”知识点的总结
    Lua习题练习(9*9乘法表,输出所指定的图像,斐波那契数列)
    对 Lua闭包 知识点的学习的总结 ,在这里和大家分享一下,希望对大家有所帮助
    Lua的string库函数、lua中string的模式匹配
  • 原文地址:https://www.cnblogs.com/wutou/p/15750926.html
Copyright © 2011-2022 走看看