0

Shell脚本curl批量检测UTM参数:3个实战脚本让营销链接巡检自动化

2026.06.15 | youres | 3次围观

做营销的人最怕什么?辛辛苦苦投放了广告,用户也点击了链接,结果后台显示流量来源是「direct」,所有UTM参数在跳转过程中全部丢失。这种问题单靠人工一个个去点、去查根本不现实,今天介绍用Shell脚本配合curl批量检测UTM参数的完整方案。

为什么需要批量检测UTM参数

UTM参数(Urchin Tracking Module)是营销活动的命根子。utm_source、utm_medium、utm_campaign这些参数用来标记流量从哪来、走的什么渠道、属于哪个活动。但凡中间经过一次重定向,参数就可能被服务器吃掉。

常见的坑包括:短链平台跳转后参数丢失、Nginx 301跳转把问号后的内容清空、CDN强制HTTPS跳转时参数被剥离。单条检测可以用浏览器开发者工具,但几十上百条链接只能靠脚本批量跑。

核心原理:curl url_effective 拿到最终地址

做批量检测依赖curl的两个参数:-L让curl跟随所有重定向,-w url_effective输出最终请求的实际URL(即重定向之后的地址)。如果UTM参数还在最终URL里,就说明跳转链路保留了参数;如果参数消失了,就说明某一级跳转出了问题。

单条检测命令长这样:

curl -sL -w "\\n%{url_effective}" -o /dev/null "https://your-domain.com/redirect?utm_source=test&utm_medium=blog&utm_campaign=q1"

输出结果就是重定向后的完整URL,直接grep看有没有utm_开头的参数即可。

方案一:基础while循环脚本

最入门的写法,从文件读取URL列表,逐行处理:

#!/bin/bash
INPUT="urls.txt"
OUTPUT="utm_check_result.txt"

echo "原始URL,最终URL,UTM参数状态" > "$OUTPUT"

while IFS= read -r url; do
    [[ -z "$url" || "$url" =~ ^# ]] && continue
    final_url=$(curl -sL -w "%{url_effective}" -o /dev/null --max-time 10 "$url")
    if echo "$final_url" | grep -q "utm_"; then
        status="保留"
    else
        status="丢失"
    fi
    echo "\\"$url\\",\\"$final_url\\",\\"$status\\"" >> "$OUTPUT"
    echo "[$status] $url -> $final_url"
done < "$INPUT"
echo "检测完成,结果已保存到 $OUTPUT"

用法很简单,新建urls.txt,每行一个营销链接,然后执行脚本。结果输出到CSV文件,用Excel或Numbers可以直接打开查看。

方案二:xargs并行加速脚本

方案一虽然能跑,但几十个链接串行检测速度太慢。换成xargs并行处理,速度直接翻几倍:

#!/bin/bash
INPUT="urls.txt"
OUTPUT="utm_check_result.csv"
MAX_JOBS=5

echo "原始URL,最终URL,跳转次数,UTM状态,检测时间" > "$OUTPUT"

check_utm() {
    url="$1"
    result=$(curl -sL -w ":::|||%{url_effective}:::|||%{num_redirects}" -o /dev/null --max-time 15 "$url")
    final_url=$(echo "$result" | awk -F':::' '{print $2}')
    redirect_count=$(echo "$result" | awk -F':::' '{print $3}')
    if echo "$final_url" | grep -qE "utm_source|utm_medium|utm_campaign"; then
        status="保留"
    else
        status="丢失"
    fi
    check_time=$(date "+%Y-%m-%d %H:%M:%S")
    echo "\\"$url\\",\\"$final_url\\",\\"$redirect_count\\",\\"$status\\",\\"$check_time\\""
}

export -f check_utm
cat "$INPUT" | grep -v "^#" | grep -v "^$" | xargs -n1 -P"$MAX_JOBS" bash -c 'check_utm "$@"' _
echo "并行检测完成,结果在 $OUTPUT"

这个脚本的亮点是:加了并发数控制(MAX_JOBS=5),避免同时发太多请求把目标服务器打爆;多了跳转次数统计字段,方便排查是不是因为跳转层级太多导致参数丢失。

方案三:带CSV报告和异常标记的完整脚本

实际工作中巡检脚本跑完了,还需要导出报告、标注异常项。这个方案把结果直接整理成带状态标注的CSV:

#!/bin/bash
INPUT="urls.txt"
REPORT="utm_audit_$(date +%Y%m%d_%H%M%S).csv"

echo "序号,原始URL,最终URL,跳转次数,UTM来源,UTM介质,UTM活动,参数状态,异常原因,检测时间" > "$REPORT"

seq=1
while IFS= read -r url; do
    [[ -z "$url" || "$url" =~ ^# ]] && continue
    result=$(curl -sL -w ":::|||%{url_effective}:::|||%{num_redirects}" -o /dev/null --max-time 15 "$url")
    final_url=$(echo "$result" | awk -F':::' '{print $2}')
    redirect_count=$(echo "$result" | awk -F':::' '{print $3}')
    utm_source=$(echo "$final_url" | grep -oP 'utm_source=\\K[^&?]+' || echo "")
    utm_medium=$(echo "$final_url" | grep -oP 'utm_medium=\\K[^&?]+' || echo "")
    utm_campaign=$(echo "$final_url" | grep -oP 'utm_campaign=\\K[^&?]+' || echo "")
    if [[ -n "$utm_source" || -n "$utm_medium" || -n "$utm_campaign" ]]; then
        status="正常"
        reason=""
    else
        status="异常"
        reason="重定向后UTM参数全部丢失"
    fi
    check_time=$(date "+%Y-%m-%d %H:%M:%S")
    echo "$seq,\\"$url\\",\\"$final_url\\",\\"$redirect_count\\",\\"$utm_source\\",\\"$utm_medium\\",\\"$utm_campaign\\",\\"$status\\",\\"$reason\\",\\"$check_time\\"" >> "$REPORT"
    [[ "$status" == "异常" ]] && echo "异常: 第${seq}条链接UTM参数丢失: $url"
    ((seq++))
done < "$INPUT"

normal_count=$(grep -c ",正常," "$REPORT")
error_count=$(grep -c ",异常," "$REPORT")
echo "===== 巡检报告汇总 ====="
echo "总检测数: $((normal_count + error_count))"
echo "正常: $normal_count"
echo "异常: $error_count"
echo "报告文件: $REPORT"

这个脚本跑完之后会输出汇总:检测了多少条、正常多少条、异常多少条。异常行在CSV里标记为「异常」状态,配合Excel的条件格式可以直接高亮出来,递给运营同事一目了然。

常见坑和排查思路

脚本跑起来发现大量参数丢失,先别急着怪服务器。从这几个方向查:

  • 重定向次数过多:有些短链经过三四跳才到落地页,中间某一跳的参数处理逻辑有问题。用curl -v看每一步的Location头,定位到具体哪一跳参数消失。
  • 问号被当成路径分隔符:Nginx rewrite里如果写成了 return 301 /newpage?$request_uri ,原来的查询参数会变成路径的一部分,导致UTM丢失。正确做法是 return 301 /newpage$is_args$args
  • CDN层面强制跳转:Cloudflare开启「始终使用HTTPS」后,如果原链接是HTTP+查询参数,跳转过程中参数可能被CDN层的规则剥离。检查CDN页面规则里有没有配置参数处理策略。
  • URL编码问题:有些短链服务会对URL参数做编码,如果编码格式和落地页解析预期不一致,参数看起来存在但实际解析不出来。用 curl -v 看请求头的完整URL原始格式。

定时任务自动巡检

手动跑一次脚本还不够,营销链接越来越多,需要定时自动跑。把脚本扔进crontab,每天早上9点自动检测一遍,有异常就发邮件告警:

0 9 * * * /path/to/check_utm.sh >> /var/log/utm_audit.log 2>&1

如果想加邮件通知,可以在脚本末尾加一行判断异常数量大于0时调用SendMail或者调用钉钉Webhook推送告警消息。

总结

Shell脚本配合curl批量检测UTM参数,本质上就是利用curl -L跟随重定向、-w url_effective输出最终地址这两个核心能力。方案一适合快速验证几条链接,方案二适合几十条链接的高效巡检,方案三适合正式环境里的日常监控和报告导出。

关键就一句话:先把单条命令跑通,再写循环;先看日志排查问题,再上并发;先有报告,再接告警。一步一步来,脚本稳了之后每天省下的手动操作时间相当可观。

相关阅读:

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论