我知道代码很乱,先将就用把:joy:
#!/bin/bash
#

# Author: Beijixs
# Version: 1.0
# Date: 2019-11-3
# Rely: python(json.tool) sort curl nslookup 

PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin

# Shell Vars

_DEBUG=false
_INFO=false
_ERR=true
Print=false
Update=false

conf="/opt/usr/local/aliyun/dns.conf"
# 配置文件路径
age_sum=0
declare -a g_pkey
declare -a g_pval
declare -a g_pkey_val
declare -a parameter=($*)   # Get the parameters given by the user.
pack_url=

RR=
DomainName=
Type=
Value=
MyIPv4=
MyIPv6=
Dev=
IP_Status=
_count=0

par_one=0
for m in ${parameter[*]};do
    case $m in
        -p|-P)
            [ -z "${U_ACK}" ]&&Print=true&&P_ACK=1&&par_one=$((++par_one))
        ;;
        -u|-U)
            [ -z "${P_ACK}" ]&&Update=true&&U_ACK=1&&par_one=$((++par_one))
        ;;
        -v|-V)
            if [ ! -z "${U_ACK}"  -o ! -z "${P_ACK}" ]&&[ -z "${D_ACK}" ];then
                _INFO=true
                I_ACK=1
            fi
        ;;
        -d|-D)
            if [ ! -z "${U_ACK}" -o ! -z "${P_ACK}" ]&&[ -z "${I_ACK}" ];then
                _DEBUG=true
                D_ACK=1
            fi
        ;;
        -h|-H)
        ;;
        *)
            echo -e "Unknown Option: \033[31m${m}\033[0m"
        ;;
    esac
done
if [ ${par_one} -eq 0 ];then
cat <<-EOF

    UsAge: aliyun.sh item

    -p|-P           Print record details.
    -u|-U           Update record value.
    -d|-D           DEBUG mode, the order of use of parameters can not be messed up.    
    -v|-V           INFO mode, the order of use of parameters can not be messed up.
    -h|-H           Display help information.

EOF
exit 12

fi

_debug(){
    ${_DEBUG} && echo -e "\033[32m[DEBUG]\033[0m: $*"
}
_info(){
    ${_INFO} && echo -e "\033[34m[INFO]\033[0m: $*"
}
_error(){
    ${_ERR} && echo -e "\033[31m[ERROR]\033[0m: $*"
}
## ===== GET IPAddress ===== ##
fun_get_ip(){

if ${Net_IP};then
    MyIPv4=$(curl -4 -s --connect-timeout 10 -m 5 "${GET_URL}")
    ${IPv6}&&MyIPv6=$(curl -6 -s --connect-timeout 10 -m 5 "${GET_URL}")
else
    MyIPv4=$(ip a s ${Dev}|grep "\<inet\>"|awk '{print $2}')
    ${IPv6}&&MyIPv6=$(ip a s ${Dev}|grep -E "\<inet6.*global"|awk '{print $2}'|awk -F/ '{print $1}')
fi
    _info "Local MyIPv4:" "$MyIPv4"
    _info "Local MyIPv6:" "$MyIPv6"
    _debug "Local MyIPv4:" "$MyIPv4"
    _debug "Local MyIPv6:" "$MyIPv6"

}

reset_func_ret(){
# Initialize variables。
    _func_ret=""
}

reset_func_vars(){
    g_pkey=()
    g_pval=()
    g_pkey_val=()
    rand_num=$(openssl rand -hex 16)
    _status=""
    _debug "Rand Number:" "${rand_num}"
}

put_param(){
    g_pkey=(${g_pkey[*]} "$1")
    g_pval=(${g_pval[*]} "$2")
    #age_sum=$((++age_sum))
    age_sum=${#g_pkey[@]}
    # 将值保存在数组中
}

# Initialize public parameters.
put_params_public(){
    put_param  "Format" "JSON"   
    put_param  "AccessKeyId" "${AccessKeyId}"   
    put_param  "Version" "2015-01-09"  
    put_param  "SignatureMethod" "HMAC-SHA1"   
    put_param  "SignatureVersion" "1.0"

    # time stamp
    local time_utc=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    put_param  "Timestamp" "${time_utc}"
    _debug "Time Stamp:" "$time_utc"
    # SigatureNonce
    put_param  "SignatureNonce" "${rand_num}"
}


put_params_DescribeDomainRecords(){

    put_param  "Action" "DescribeSubDomainRecords"
    put_param  "DomainName" "${DomainName}"
    put_param  "SubDomain" "${SubDomain}"
    put_param  "RRKeyWord" "${RR}"
    put_param  "Type" "${Type}"
}

put_params_UpdateDomainRecord(){

    put_param  "Action" "UpdateDomainRecord"
    put_param  "RecordId" "${RecordId}"
    put_param  "RR" "${RR}"
    put_param  "Type"  "${Type}"
    put_param  "Value" "${Value}"
}

put_params_AddDomainRecord(){

    put_param  "Action" "AddDomainRecord"
    put_param  "DomainName" "${DomainName}"
    put_param  "RR" "${RR}"
    put_param  "Type" "${Type}"
    put_param  "Value" "${Value}"

}

fun_comb(){
    reset_func_ret
    local url
    local key val key_code val_code
    # Encode "key" and "value" respectively.
    # Sort Key


    local I=0
    while [ $I -lt ${age_sum} ];do
        eval key="${g_pkey[$I]}"
        eval val="${g_pval[$I]}"
        fun_encode "$key"
        key_code="${_func_ret}"
        g_pkey[$I]=${key_code}
        fun_encode "$val"
        val_code="${_func_ret}"
        g_pval[$I]=${val_code}    
        I=$((++I))
    done
    # 对key和value分别进行编码,并替换数组中原有的值

    for i in `seq 0 $((${age_sum}-1))`;do
        declare -a g_pkey_val[$i]="${g_pkey[$i]}=${g_pval[$i]}"
    done
    # 将两个数组中的值结合,key=value,并保存在新的数组中
    # key=value 
    g_pkey_val=($(
        for m in $(seq 0 $((${#g_pkey_val[*]}-1)));do
            echo ${g_pkey_val[$m]}
        done| LC_COLLATE=C sort
    ))  # 对数组进行排序
    _debug "Sort:" "${g_pkey_val[*]}"
    # Sort key
    local I=0
    while [ $I -lt ${#g_pkey_val[*]} ];do
        url="$url${g_pkey_val[$I]}&"
        let I++
    done    # 结合url
    _debug "Pack Url:" "$url"
    # Delete last "&"
    url=$(echo $url|grep -o ".*[^&]")
    # _func_ret=$url
    pack_url=$url
    _debug "Initial URL:" "$pack_url"
}

fun_encode(){
    reset_func_ret
    local string="${1}"
    local strlen="${#string}"
    local encoded=""
    local count s d

    count=0
    while [ $count -lt $strlen ];do
        s=${string:$count:1}
        case "$s" in
            [-_.~a-zA-Z0-9])
                d=${s}
            ;;
            *)
                d=$(printf "%%%02X" "'$s")
        esac
        encoded="${encoded}${d}"
        count=$((++count))
    done
    _func_ret=$encoded
    # 编码算法
}

string_to_sign(){
    local string=${pack_url}
    fun_encode "$string"
    string="GET&%2F&${_func_ret}"
    _debug "String to be signed:" "$string"
    local key_sign="${AccessKeySec}&"
    str_sign=$(echo -n "$string"|openssl dgst -binary -sha1 -hmac ${key_sign} | openssl enc -base64)
    _debug "Signature result:" "${str_sign}"
    fun_encode "$str_sign"
    _debug "Coding result:" "${_func_ret}"
    req_addr="https://alidns.aliyuncs.com/?${pack_url}&Signature=${_func_ret}"
    _debug "Real request URL:" "$req_addr"
}

fun_update(){
    reset_func_vars     # Initialize variables and arrays.
    put_params_public   # Defining public parameters.
    put_params_UpdateDomainRecord
    fun_comb    # Sort parameters and combine urls.
    string_to_sign  # signature

    _info "Result"
    _debug "Result"
    #curl -s ${req_addr} |python -m json.tool
    local INFO=$(curl -s ${req_addr} --silent --connect-timeout 10 -w "Status:%{http_code}\n")
    _status=$(echo ${INFO}|grep -o "Status.*"|awk -F: '{print $2}' )
    _debug "${INFO}"
    _info "${INFO}"

    if [ ${_status} = 200 ];then
        return 0
    fi
        return 1  

}
fun_add_record(){
    _info "Adding record..."
    _debug "Adding record..."
    reset_func_vars     # Initialize variables and arrays.
    put_params_public   # Defining public parameters.
    put_params_AddDomainRecord
    fun_comb
    string_to_sign  # signature
    _info "Result"
    _debug "Result"
    local INFO=$(curl -s ${req_addr} --silent --connect-timeout 10 -w "Status:%{http_code}\n")
    _status=$(echo ${INFO}|grep -o "Status.*"|awk -F: '{print $2}' )
    _debug "${INFO}"
    _info "${INFO}"
    if [ ${_status} = 200 ];then
        _info "Add record successfully."
        _debug "Add record successfully."
        return 0
    fi
        _info "Add record failed.Do you own the domain name?(${DomainName})"
        _debug "Add record failed.Do you own the domain name?(${DomainName})"
        return 100

}

fun_check(){
    local SubDomain=${SubDomain}
    if [ ${SubDomain:0:1} == "@" ];then
        SubDomain=${DomainName}
    fi
    #local IP=$(dig @${DNS_Server} ${SubDomain} +short)
    local IP="$(nslookup -query=${Type} ${SubDomain} ${DNS_Server}|grep "Name" -A 1|tail -1|awk '{print $2}')"
    _debug "Last IP:" ${IP}
    _info "Last IP:" ${IP}
    if [ "$IP" == "${Value}" ];then
        _info "SubDomain: ${SubDomain}"
        _debug "SubDomain: ${SubDomain}"
        _info  "The IP address is the same as the local IP address. No need to modify it."
        _debug  "The IP address is the same as the local IP address. No need to modify it."
        return 0
    else
        return 1
    fi

}

fun_print(){
    [ "${IPv6}" = "false" -a ${Type} = "AAAA" ]&&return 133
    reset_func_vars     # Initialize variables and arrays.
    put_params_public   # Defining public parameters.
    put_params_DescribeDomainRecords    # Defining unique parameters.
    fun_comb    # Sort parameters and combine urls.
    string_to_sign  # signature
    _info "Request completed:"
    #curl -s  $req_addr|python -m json.tool
    curl -s $req_addr|python -m json.tool|grep -E "DomainName|RR|Type|Value|RecordId|Message"|sed "s#\"##g;s#,##;s#^[[:space:]]*##g"| \
    awk -v b=${SubDomain} 'BEGIN{print "\n------------------------------------\n","   SubDomain :  ",b,"\n------------------------------------"} \
    BEGIN{printf "\tKey\t\tValue\n------------------------------------\n"} \
    {printf "    %-16s%-10s\n",$1,$2} \
    END{printf "------------------------------------\n\n"}'

}

fun_check_id(){
    local check=${1}
    local tmp=""
    if [ -z "${1}" ];then
        _debug "RecordId does not exist." 
        _debug "Find recordId."
        tmp=$(fun_print|grep "RecordId"|awk '{print $2}')
        if [ -z ${tmp} ];then
            _debug "No such record."
            return 20
        else
            _debug "RecordId" "${tmp}"
            RecordId=${tmp}
            sed -i "s#^Domain \"${Type}\" \"${DomainName}\" \"${RR}\".*#Domain \"${Type}\" \"${DomainName}\" \"${RR}\" \"$RecordId\"#" ${conf}
            return 0
        fi
    fi
        return 0
}

fun_to_update(){
    if [ ${IP_Status} -eq 1 -a ${Type} = "AAAA" ];then
        _info "Skip:" "Ipv6 failed to get rid of ipv6 record updates."
        _debug "Skip:" "Ipv6 failed to get rid of ipv6 record updates."
        return 3
    elif [ ${IP_Status} -eq 2 -a ${Type} = "A" ];then
        _info "Skip:" "Ipv4 failed to get rid of ipv6 record updates."
        _debug "Skip:" "Ipv4 failed to get rid of ipv6 record updates."
        return 4
    fi

    if fun_check;then
        return 0
    fi

    if fun_check_id ${RecordId};then
        if fun_update;then
            _debug "Update completed."
            _info "Update completed."
            return 0
        else    
            _error "Update failed." "Try updating \"RecordId\"."
            RecordId=""
            if fun_check_id ${RecordId};then
                if fun_update;then
                    _debug "Update completed."
                    _info "Update completed."
                    return 0
                fi
                    _error "Update failed.(Unknown reason)"

            else
                _error "No such record." "Will automatically add records."
                fun_add_record
                # ADD Record
            fi
        fi
    else
        _error "No such record." "Will automatically add records."
        # ADD Record
        fun_add_record
    fi

}

fun_check_conf(){
    local index=0
    local Key=()
    local Value=()
    Key=("AccessKeyId" "AccessKeySec" "Dev" "Net_IP" "GET_URL" "DNS_Server" "IPv6")
    Value=("${AccessKeyId}" "${AccessKeySec}" "${Dev}" "${Net_IP}" "$GET_URL" "${DNS_Server}" "${IPv6}")
    for I in ${Key[*]};do
        if [ -z "${Value[$index]}" ];then
            case $I in
                Net_IP|AccessKeyId|AccessKeySec)
                _error "$I" "This value cannot be empty"
                exit 15
                ;;
                GET_URL)
                    GET_URL="ip.sb"
                    _info "Default GET_URL:" "${GET_URL}"
                    _debug "Default GET_URL:" "${GET_URL}"
                ;;
                DNS_Server)
                    DNS_Server="dns23.hichina.com"
                    _info "Default DNS_Server:" "${DNS_Server}"
                    _debug "Default DNS_Server:" "${DNS_Server}"
                ;;
                IPv6)
                    IPv6=false
                    _info "Default IPv6:" "${IPv6}"
                    _debug "Default IPv6:" "${IPv6}"
                ;;
            esac
        fi
        index=$((++index))
    done

    [ ${IPv6} != "true" -a ${IPv6} != "false" ]&&_error "IPv6:" "Unknown value.(Value: true|false)"&&exit 12
    [ ${Net_IP} != "true" -a ${Net_IP} != "false" ]&&_error "Net_IP:" "Unknown value.(Value: true|false)"&&exit 12
    [ ${Net_IP} == "false" -a -z "${Dev}" ]&&_error "\"Net_IP\" is false, \"Dev\" cannot be empty"&&exit 12

}

fun_check_ip(){
    case ${IPv6} in
        true)
            if [ ! -z "${MyIPv4}" -a ! -z "${MyIPv6}" ];then
                IP_Status=0
            elif [ ! -z "${MyIPv4}" -a -z "${MyIPv6}" ];then
                IP_Status=1
                _error "Skip:" "Ipv6 address acquisition failed, will not update the A record"
            elif [ -z "${MyIPv4}" -a ! -z "${MyIPv6}" ];then
                IP_Status=2
                _error "Skip:" "Ipv4 address acquisition failed, will not update A record."
            else
                _error "Can't get ipv4 and ipv6 address."
                exit 52
            fi
        ;;
        false)
            IP_Status=1
            _info "Skip:" "Ipv6 record update has been closed and AAAA record will not be updated."
            if [ -z "${MyIPv4}" ];then
                _error "Failed to get Ipv4 address."
                exit 51
            fi
        ;;
    esac
}

fun_check_domain(){
    local D_Key=("Type" "DomainName" "RR" "RecordId")
    local D_Val=("${Type}" "${DomainName}" "${RR}" "${RecordId}")
    for i in {0..2};do
        if [ -z "${D_Val[$i]}" ];then
            _error "${D_Key[$i]}" "None"
            return 25
        fi
    done
    if [ ${Type} = "A" ];then
        Value=${MyIPv4}
    elif [ ${Type} = "AAAA" ];then 
        Value=${MyIPv6}
    else
        _error "Unknow Type:" "${Type}"
        return 12
    fi

    [ -z "${D_Val[3]}" ]&&_info "RecordId:" "None"
    _debug "SubDomain:" "${RR}.${DomainName}"
    _info "SubDomain:" "${RR}.${DomainName}"

    return 0
}
# 引入配置文件
Domain(){
# Main function
_debug "--------------------------------------------------------------------------------------------------------"
_info  "--------------------------------------------------------------------------------------------------------"

    DomainName="${2}" 
    Type="${1}"
    RR="${3}"
    SubDomain="${RR}.${DomainName}"
    RecordId=${4}

    if [ ${_count} = 0 ];then   
    # check_conf
        fun_check_conf
    # get_ip
        fun_get_ip
    # check_ip
        fun_check_ip
        _count=1
    fi

    if fun_check_domain;then
        ${Print}&&fun_print
        ${Update}&&fun_to_update
    fi

}
. ${conf}

配置文件需要严格遵守格式
# AccessKeyId=""
# AccessKeySec=""
#

AccessKeyId=""
AccessKeySec=""

# Set the network interface to obtain the ip address. This value is invalid when "Net_IP" is "true". 
Dev="ppp0"
# "Net_IP" is not available, boolean value
# Net_IP=false
Net_IP=false
# This value is not available when "Net_IP" is "true".
GET_URL="ip.sb"
# On IPv6,Defalut flase
IPv6=true

# Aliyun "DNS" server address, if not clear, please do not modify.
#

DNS_Server="dns23.hichina.com"

# Domian "Type" "DomainName" "RRKeyWord" "RecordId"
# Do not know "RecordId", please leave it blank. as follows.
# Domain "A" "beijixs.cn" "www"
#
# The "RecordId" will be automatically added to the configuration file in the second parsing, please do not manually define.

Domain "A" "beijixs.cn" "blog" 

END
Last modification:November 15th, 2019 at 02:37 pm
If you think my article is useful to you, please feel free to appreciate