安装expect

$ sudo apt install expect

remote_cmd.sh

#!/bin/bash

function usage
{
    echo "USAGE: $0 [OPTION]"
    printf "  远程批量执行命令\n"
    printf "\n"
    printf "Examples:\n"
    printf "  $0 -u root -p RDC -c 'touch ~/test_touch'\n"
    printf "\n"
    printf "Operation:\n"
    printf "  -h\t\t 显示当前页面\n"
    printf "  -u\t\t 被执行机器用户名\n"
    printf "  -p\t\t 需要执行命令机器的密码\n"
    printf "  -c\t\t 需要执行的命令\n"
    exit 1;
}

while getopts "c:u:p:h" arg #选项后面的冒号表示该选项需要参数
do
        case $arg in
             h)
                usage
                ;;
             c)
                cmd=$OPTARG
                ;;
             p)
                Password=$OPTARG
                ;;
             u)
                User=$OPTARG
                ;;
             ?)  #当有不认识的选项的时候arg为?
                echo "unkonw argument"
                exit 1
        break
        esac
done

if [ ! $cmd ];then
    printf '\e[1;31m !!! 必须指定需要执行的命令行 !!! \e[0m\n\n'
    usage
fi

if [ ! $Password ];then
    printf '\e[1;31m !!! 必须指定被执行机器的密码 !!! \e[0m\n\n'
    usage
fi


function find_host
{
    hosts=(`cat hosts | awk '{print $0}'| sort 2>/dev/null`)
    num=${#hosts[@]}

    for ((i=0;i<$num;i++))
    do
        status=`ping ${hosts[$i]} -c 1 -W 1 | grep -c ' 0% packet loss'`
        if [ $status -eq $1 ];then
            echo ${hosts[$i]}
        fi
    done
}

hostsup=(`find_host 1`)
hostsdown=(`find_host 0`)

if [ ${#hostsdown[@]} -gt 0 ];then
    echo -e '\e[0;34m#########################################################\e[0m'
    echo -e '\e[0;34m下面的机器无法连接:\e[0m'
    echo -e "\e[0;31m${hostsdown[@]}\e[0m"
    echo -e '\e[0;34m#########################################################\e[0m'
    echo ''
fi

echo -e '\e[0;34m#########################################################\e[0m'
echo -e "\e[0;34m将会在下面机器执行 '$cmd':\e[0m"
echo -e "\e[0;32m${hostsup[@]}\e[0m"
echo -e '\e[0;34m#########################################################\e[0m'
echo ''

while true; do
    printf "Do you wish to Run cmd '$cmd' on those computes?(\e[0;32myes\e[0m/\e[0;31mno\e[0m)"
    read yn
    case $yn in
        [Yy]* ) break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no";;
    esac
done

function run_cmd
{
    host=$1
    if [ $User == 'root' ];then
        bash_line="*]#\ "
    else
        bash_line="*$\ "
    fi
    expect <<EOD
spawn ssh $User@$host -p 22
expect {
    "yes/no)?\ " {send "yes\r";exp_continue}
    "*assword:\ " {send "$Password\r"}
    "$bash_line" {send "\r"}
}

expect "$bash_line" {send "$cmd\r"}

expect "$bash_line" {send "exit\r"}

expect eof
EOD
}


for host in ${hostsup[@]}
do
    run_cmd $host
done

评论

请输入您的评论. 可以使用维基语法: