1. 程式人生 > >基於shell實現向多臺伺服器拷貝hosts檔案

基於shell實現向多臺伺服器拷貝hosts檔案

寫這個指令碼的目的是在生產環境中向多個伺服器拷貝hosts檔案,能滿足自己的使用要求。

github: https://github.com/charnet1019/auto-scp-files.git

注意:

需要安裝expect

#!/bin/bash
##########################################################
#
# Copyright (2017-10-21, )
#
# Author: [email protected]
# Last modified: 2017-10-22 00:06
# Description: 
#
##########################################################

# definition IP dictionary array
declare -A IPListDict

# 所有主機預設使用root帳號
USERNAME=root
# 本地要拷貝的檔案
LOCAL="/etc/hosts"
# 拷貝到遠端主機的位置
REMOTE="/tmp"

# 主機IP地址和密碼,每行一個主機
IPListDict=(
[192.168.2.4]="secret"
)

ssh_key_base_dir=~/.ssh
ssh_known_hosts=$ssh_key_base_dir/known_hosts
SCP=/usr/bin/scp

DATETIME=`date "+%F %T"`

success() {
    printf "\r$DATETIME [ \033[00;32mINFO\033[0m ]%s\n" "$1"
}

warn() {
    printf "\r$DATETIME [\033[0;33mWARNING\033[0m]%s\n" "$1"
}

fail() {
    printf "\r$DATETIME [ \033[0;31mERROR\033[0m ]%s\n" "$1"
}

usage() {
    echo "Usage: ${0##*/} {info|warn|err} MSG"
}

log() {
    if [ $# -lt 2 ]; then
        log err "Not enough arguments [$#] to log."
    fi

    __LOG_PRIO="$1"
    shift
    __LOG_MSG="$*"

    case "${__LOG_PRIO}" in
        crit) __LOG_PRIO="CRIT";;
        err) __LOG_PRIO="ERROR";;
        warn) __LOG_PRIO="WARNING";;
        info) __LOG_PRIO="INFO";;
        debug) __LOG_PRIO="DEBUG";;
    esac

    if [ "${__LOG_PRIO}" = "INFO" ]; then
        success " $__LOG_MSG"
    elif [ "${__LOG_PRIO}" = "WARNING" ]; then
        warn " $__LOG_MSG"
    elif [ "${__LOG_PRIO}" = "ERROR" ]; then
        fail " $__LOG_MSG"
    else
       usage
    fi
}

is_exist_expect() {
    if ! which expect &> /dev/null; then
        return 1
    fi

    return 0
}

install_expect() {
    yum -y install expect &> /dev/null
}

check_expect() {
    is_exist_expect
    if [ $? -eq 1 ]; then
        log warn "No expect command and try to install, please wait..."
        install_expect
        is_exist_expect
        if [ $? -eq 1 ]; then
            log err "Installation failed, please install the expect command manually."
            exit 1
        else
            log info "Installation successed."
        fi
    fi
}

#is_exist_hosts() {
#    local FILE=$1
#
#    [ -f ${FILE} ] && return 0 || return 1
#}

get_cipher() {
    local IP=$1

    for key in ${!IPListDict[@]}; do
        if [[ X"$IP" == X"$key" ]]; then
            PASSWORD="${IPListDict[$key]}"
        fi
    done
}

exec_cp() {
    for ip in ${!IPListDict[@]}; do
        get_cipher $ip
        expect -c  <<- EOF &> /dev/null "
            spawn $SCP -r $LOCAL 
[email protected]
$ip:$REMOTE expect { \"(yes/no)?\" { send \"yes\r\" expect { "*assword" { send \"$PASSWORD\r\" } } } "*assword*" { send \"$PASSWORD\r\" } expect "100%" expect eof } catch wait retVal exit [lindex \$retVal 3]" EOF if [ $? -eq 0 ]; then log info "The file $LOCAL copy to the remote host $ip successed." else log err "The file $LOCAL copy to the remote host $ip failed." fi done } # main check_expect exec_cp