执行mtr网络路由测试,并为每个路由节点 IP 查询属地信息,最终输出包含 IP 属地的 mtr 测试结果 bash shell脚本

#!/bin/bash
##############################################################################
# 脚本名称: mtr_with_ip_location.sh
# 脚本功能: 执行MTR路由测试,并自动查询每个节点IP的属地信息
# 使用说明: ./脚本名 <目标IP>
# 依赖工具: mtr、curl、jq、iconv、awk、sed、grep
# 示例: ./mtr_with_ip_location.sh 23.95.215.199
# 注意事项:
#   1. 需确保能访问http://whois.pconline.com.cn(IP属地查询接口)
#   2. 执行时间取决于MTR节点数(每个节点curl超时60秒,默认重试3次)
##############################################################################

# ======================== 配置项 ========================
TARGET_IP="$1"                  # 目标IP(从参数传入)
CURL_TIMEOUT=10                 # curl超时时间(缩短为10秒,原60秒过长)
CURL_RETRY=2                    # curl重试次数
USER_AGENT="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36"
LOG_FILE="/var/log/mtr_location.log" # 运行日志

# ======================== 日志函数 ========================
log() {
    local level=$1
    local msg=$2
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] [$level] $msg" >> ${LOG_FILE}
}

# ======================== 随机生成合法IP(X-Forwarded-For) ========================
generate_random_ip() {
    # 生成1-254之间的随机数(IP段合法范围)
    local a=$((RANDOM % 254 + 1))
    local b=$((RANDOM % 255))
    local c=$((RANDOM % 255))
    local d=$((RANDOM % 255))
    echo "${a}.${b}.${c}.${d}"
}

# ======================== 查询IP属地 ========================
get_ip_location() {
    local ip=$1
    local random_ip=$(generate_random_ip)
    local xff_header="X-Forwarded-For: ${random_ip}"
    
    log "INFO" "查询IP ${ip} 的属地信息"
    
    # 调用太平洋电脑网IP属地接口
    local response=$(curl -m ${CURL_TIMEOUT} \
                          --retry ${CURL_RETRY} \
                          --header "${xff_header}" \
                          -A "${USER_AGENT}" \
                          -sLk -o - \
                          "http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=${ip}" 2>/dev/null)
    
    # 处理响应:GBK转UTF-8 → jq解析 → 提取addr字段 → 清理特殊字符
    local location=$(echo "${response}" | \
                     iconv -f gbk -t utf-8//IGNORE 2>/dev/null | \
                     jq -r '.addr // ""' 2>/dev/null | \
                     sed -e 's/[() ]//g' -e 's/[[:space:]]//g' 2>/dev/null)
    
    # 容错:若查询失败,返回"未知属地"
    if [[ -z "${location}" || "${location}" == "null" ]]; then
        location="未知属地"
        log "WARN" "IP ${ip} 属地查询失败,响应: ${response:0:100}..."
    else
        log "INFO" "IP ${ip} 属地: ${location}"
    fi
    
    echo "${location}"
}

# ======================== 参数校验 ========================
if [[ $# -ne 1 ]]; then
    echo "用法: $0 <目标IP>"
    echo "示例: $0 23.95.215.199"
    exit 1
fi

# 校验目标IP格式
if ! echo "${TARGET_IP}" | egrep -q "^([0-9]{1,3}\.){3}[0-9]{1,3}$"; then
    echo "错误:目标IP格式无效!"
    exit 1
fi

# ======================== 执行MTR并解析 ========================
log "INFO" "开始执行MTR测试,目标IP: ${TARGET_IP}"

# 执行MTR(CSV格式、报告模式、数字格式)
mtr -C -r -n "${TARGET_IP}" 2>/dev/null | while read line; do
    # 提取行中的IP地址
    ip=$(echo "${line}" | egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | head -n1)
    
    if [[ -n "${ip}" ]]; then
        # 有IP,查询属地并输出
        location=$(get_ip_location "${ip}")
        echo "${line} | 属地: ${location}"
    else
        # 无IP,直接输出原始行
        echo "${line}"
    fi
done

log "INFO" "MTR测试完成,目标IP: ${TARGET_IP}"
echo "MTR测试完成!详细日志请查看: ${LOG_FILE}"

命令行版本:

mtr -C -r -n 23.95.215.199 2>/dev/null |while read line;do npk="$(echo "$line" |egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}")";if [ -n "$npk" ];then sdihepe="X-Forwarded-For: $(echo |awk -v A=$(date +%S%N) '{srand();a=int(A*rand())%254+1;srand();b=int(A*rand())%255+1;srand();c=int(A*rand())%253+1;srand();d=int(A*rand())%252+1;printf"%s.%s.%s.%s\n",a,b,c,d}')";ounerilesal="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36";roltsarsn="$(curl -m 60 --retry 3 --header "$sdihepe" -A "$ounerilesal" -sLk -o - "http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=${npk}" |iconv -f gbk -t utf-8//IGNORE |jq . |awk -F'["]' '/"addr":/{gsub(" ","",$4);print $4}' |sed 's/)\|(//g')";echo "$line $roltsarsn";else echo "$line";fi;done
Categories: 系统运维