0

Shell脚本UTM参数巡检定时任务配置:3个实战方案让营销链接追踪完全自动化

2026.06.15 | youres | 2次围观

# Shell脚本UTM参数巡检定时任务配置:3个实战方案让营销链接追踪完全自动化

UTM参数是营销人员追踪流量来源的利器,但手动检查成百上千个营销链接的UTM参数是否保留,简直是噩梦。一旦重定向配置不当,UTM参数在跳转过程中丢失,你投入的营销费用就打了水漂,还不知道问题出在哪里。

本文将手把手教你用Shell脚本+crontab搭建一套UTM参数自动巡检系统,让营销链接追踪完全自动化,不用人盯。

## 为什么需要UTM参数自动巡检?

在实战中,UTM参数丢失的场景比比皆是:

- Nginx重定向配置错误:`return 301 https://example.com;` 少了 `$is_args$args`,UTM参数直接被砍掉 - CDN层跳转问题:Cloudflare等CDN的自动HTTPS跳转,可能悄无声息地剥离查询参数 - 多次重定向链路:短链→中间页→落地页,任何一环配置不当,UTM就断了 - 后端应用重定向:Java/Python/PHP的302跳转,如果代码没处理查询参数,UTM同样丢失

手动检查?一个中型营销活动动辄几百个追踪链接,人工逐个`curl`检测?不现实。

## 方案一:基础版——curl批量检测UTM参数脚本

先上最基础的脚本,适合初学者快速上手。

### 核心思路

用`curl -L -w url_effective`追踪完整重定向链路,检查最终URL是否还带着UTM参数。

### 完整脚本


#!/bin/bash
# UTM参数巡检基础版
# 用法: ./utm_check_basic.sh url_list.txt

URL_FILE="$1" if [ -z "$URL_FILE" ] || [ ! -f "$URL_FILE" ]; then echo "用法: $0 " exit 1 fi

TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') LOG_FILE="utm_check_$(date '+%Y%m%d_%H%M%S').log"

echo "========== UTM参数巡检报告 ==========" | tee -a "$LOG_FILE" echo "检测时间: $TIMESTAMP" | tee -a "$LOG_FILE" echo "" | tee -a "$LOG_FILE"

while IFS= read -r url || [ -n "$url" ]; do # 跳过空行和注释 [[ -z "$url" || "$url" =~ ^# ]] && continue echo "正在检测: $url" | tee -a "$LOG_FILE" # 用curl -L跟随重定向,用-w url_effective获取最终地址 final_url=$(curl -sS -L -o /dev/null -w "%{url_effective}" "$url") # 检查最终URL是否包含utm_参数 if echo "$final_url" | grep -q 'utm_'; then echo " [OK] UTM参数保留正常" | tee -a "$LOG_FILE" echo " 最终地址: $final_url" | tee -a "$LOG_FILE" else echo " [FAIL] UTM参数丢失!" | tee -a "$LOG_FILE" echo " 最终地址: $final_url" | tee -a "$LOG_FILE" # 标记失败,方便后续排查 echo "$url" >> "utm_fail_list.txt" fi echo "" | tee -a "$LOG_FILE" # 避免请求过快 sleep 1 done < "$URL_FILE"

echo "========== 检测完成 ==========" | tee -a "$LOG_FILE" echo "详细日志: $LOG_FILE" [ -f "utm_fail_list.txt" ] && echo "失败列表: utm_fail_list.txt"

### URL列表文件格式

# url_list.txt - UTM参数检测列表 https://example.com/landing-page?utm_source=baidu&utm_medium=cpc&utm_campaign=summer_sale https://short.url/abc123?utm_source=wechat&utm_medium=social

### 脚本解析

1. `curl -L`:跟随重定向,最多跳50次(默认值) 2. `-o /dev/null`:不下载内容,只关心跳转 3. `-w "%{url_effective}"`:输出最终跳转地址 4. `grep -q 'utm_'`:检查最终地址是否还带着UTM参数

这个脚本的优点是简单直接,缺点是只能看到"最终结果",无法看到"中间跳转过程"。

## 方案二:进阶版——逐层追踪重定向链路

要真正搞清楚UTM参数"在哪一层丢失的",需要逐层检查每一跳的Location头。

### 核心思路

用`curl -I -L`逐层获取响应头,提取每一跳的Location,对比UTM参数在哪一层消失。

### 完整脚本


#!/bin/bash
# UTM参数巡检进阶版:逐层追踪重定向链路
# 用法: ./utm_check_advanced.sh 

TARGET_URL="$1" if [ -z "$TARGET_URL" ]; then echo "用法: $0 " exit 1 fi

echo "========== 逐层追踪重定向链路 ==========" echo "初始URL: $TARGET_URL" echo ""

# 用curl -I -L逐层获取响应头 # 用一个临时文件存储所有响应头 TEMP_HEADERS=$(mktemp)

curl -sS -I -L "$TARGET_URL" -o "$TEMP_HEADERS" 2>/dev/null

# 解析每一跳 jump_count=0 while IFS= read -r line; do if echo "$line" | grep -qi '^HTTP/'; then jump_count=$((jump_count + 1)) http_status=$(echo "$line" | awk '{print $2}') echo "第 $jump_count 跳: HTTP $http_status" elif echo "$line" | grep -qi '^Location:'; then location=$(echo "$line" | sed 's/^Location: //i' | tr -d '\r') echo " Location: $location" # 检查这一跳是否还带着utm_参数 if echo "$location" | grep -q 'utm_'; then echo " [OK] 本跳UTM参数保留" else # 检查上一跳的URL是否带UTM,如果带了但这一跳没了,就是在这一跳丢失的 if [ $jump_count -gt 1 ]; then echo " [WARN] UTM参数可能在此跳丢失!" fi fi fi done < "$TEMP_HEADERS"

echo "" echo "========== 最终地址 ==========" final_url=$(curl -sS -L -o /dev/null -w "%{url_effective}" "$TARGET_URL") echo "$final_url"

if echo "$final_url" | grep -q 'utm_'; then echo "[OK] 最终地址UTM参数保留" else echo "[FAIL] 最终地址UTM参数丢失!" fi

rm -f "$TEMP_HEADERS"

### 输出示例

========== 逐层追踪重定向链路 ========== 初始URL: https://short.url/abc?utm_source=baidu&utm_medium=cpc

第 1 跳: HTTP 301 Location: https://www.example.com/intermediate?utm_source=baidu&utm_medium=cpc [OK] 本跳UTM参数保留 第 2 跳: HTTP 302 Location: https://www.example.com/landing-page [WARN] UTM参数可能在此跳丢失!

========== 最终地址 ========== https://www.example.com/landing-page [FAIL] 最终地址UTM参数丢失!

从输出可以清晰看到:UTM参数在第2跳(302重定向)被丢弃了。接下来就去查这一层的Nginx或后端代码配置。

## 方案三:生产级——crontab定时巡检+告警

把上面两个方案整合,加上定时执行和告警通知,就是一套完整的生产级UTM参数巡检系统。

### 完整脚本(生产级)


#!/bin/bash
# UTM参数定时巡检脚本(生产级)
# 功能: 批量检测UTM参数 + 生成CSV报告 + 异常告警
# 推荐部署: crontab每日执行

# ========== 配置区 ========== URL_LIST_FILE="./utm_url_list.txt" # URL列表文件 LOG_DIR="./utm_check_logs" # 日志目录 CSV_REPORT="./utm_report_$(date '+%Y%m%d').csv" # CSV报告文件 ALERT_THRESHOLD=5 # 失败超过5个就告警 ADMIN_EMAIL="admin@example.com" # 告警邮件地址

# ========== 初始化 ========== mkdir -p "$LOG_DIR" TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') LOG_FILE="$LOG_DIR/utm_check_$(date '+%Y%m%d_%H%M%S').log"

# CSV报告标题行(如果文件不存在就创建) if [ ! -f "$CSV_REPORT" ]; then echo "检测时间,URL,初始UTM,最终URL,是否保留,跳转次数,备注" > "$CSV_REPORT" fi

# ========== 开始检测 ========== echo "========== UTM参数定时巡检 ==========" | tee -a "$LOG_FILE" echo "检测时间: $TIMESTAMP" | tee -a "$LOG_FILE" echo "URL列表: $URL_LIST_FILE" | tee -a "$LOG_FILE" echo "" | tee -a "$LOG_FILE"

fail_count=0 success_count=0

while IFS= read -r url || [ -n "$url" ]; do [[ -z "$url" || "$url" =~ ^# ]] && continue echo "检测: $url" | tee -a "$LOG_FILE" # 提取初始UTM参数 initial_utm=$(echo "$url" | grep -o 'utm_[^&]*&*' | tr -d '\n') # 获取最终URL和跳转次数 final_url=$(curl -sS -L -o /dev/null -w "%{url_effective}" "$url" 2>/dev/null) redirect_count=$(curl -sS -L -o /dev/null -w "%{num_redirects}" "$url" 2>/dev/null) # 判断是否保留UTM if echo "$final_url" | grep -q 'utm_'; then utm_preserved="是" success_count=$((success_count + 1)) note="正常" else utm_preserved="否" fail_count=$((fail_count + 1)) note="UTM参数丢失" # 逐层追踪,找出丢失位置 temp_headers=$(mktemp) curl -sS -I -L "$url" -o "$temp_headers" 2>/dev/null lost_at=$(grep -i 'Location:' "$temp_headers" | grep -v 'utm_' | head -1 | sed 's/^Location: //i' | tr -d '\r') [ -n "$lost_at" ] && note="UTM在第1跳丢失: $lost_at" rm -f "$temp_headers" fi # 写入CSV echo "\"$TIMESTAMP\",\"$url\",\"$initial_utm\",\"$final_url\",\"$utm_preserved\",\"$redirect_count\",\"$note\"" >> "$CSV_REPORT" echo " 最终URL: $final_url" | tee -a "$LOG_FILE" echo " 跳转次数: $redirect_count" | tee -a "$LOG_FILE" echo " UTM保留: $utm_preserved" | tee -a "$LOG_FILE" echo "" | tee -a "$LOG_FILE" sleep 0.5 done < "$URL_LIST_FILE"

# ========== 统计摘要 ========== total=$((success_count + fail_count)) echo "========== 检测摘要 ==========" | tee -a "$LOG_FILE" echo "总检测数: $total" | tee -a "$LOG_FILE" echo "正常: $success_count" | tee -a "$LOG_FILE" echo "异常: $fail_count" | tee -a "$LOG_FILE" echo "CSV报告: $CSV_REPORT" | tee -a "$LOG_FILE" echo "" | tee -a "$LOG_FILE"

# ========== 告警逻辑 ========== if [ "$fail_count" -ge "$ALERT_THRESHOLD" ]; then echo "[ALERT] 检测到 $fail_count 个UTM参数丢失,超过阈值 $ALERT_THRESHOLD,发送告警..." | tee -a "$LOG_FILE" # 邮件告警(需要系统配置mail或sendmail) alert_msg="UTM参数巡检告警\n\n检测时间: $TIMESTAMP\n异常数量: $fail_count / $total\n\n详情请查看报告: $CSV_REPORT" echo -e "$alert_msg" | mail -s "UTM参数巡检告警" "$ADMIN_EMAIL" 2>/dev/null # 如果有配置钉钉机器人,也可以在这里调用 # 参考: curl重定向异常钉钉告警配置相关文章 echo "[ALERT] 告警已发送" | tee -a "$LOG_FILE" fi

echo "========== 巡检完成 ==========" | tee -a "$LOG_FILE"

### 配置crontab定时执行


# 编辑crontab
crontab -e

# 添加以下行(每天早上9点执行) 0 9 * * * /path/to/utm_check_production.sh >> /path/to/cron.log 2>&1

# 或者每6小时执行一次 0 */6 * * * /path/to/utm_check_production.sh

### CSV报告示例

csv 检测时间,URL,初始UTM,最终URL,是否保留,跳转次数,备注 2026-06-15 09:00:00,https://example.com/landing?utm_source=baidu,utm_source=baidu&utm_medium=cpc,https://www.example.com/landing?utm_source=baidu&utm_medium=cpc,是,1,正常 2026-06-15 09:00:05,https://short.url/abc?utm_source=wechat,utm_source=wechat&utm_medium=social,https://www.example.com/home,否,2,UTM在第1跳丢失

## 内链推荐

如果你在配置Nginx重定向时遇到UTM参数丢失问题,可以参考这些实战教程:

- Nginx重定向保留UTM参数最佳实践:详解return和rewrite两种重定向方式如何正确保留查询参数 - curl追踪重定向链路检查UTM参数:用curl命令逐层诊断UTM参数在哪一次跳转中丢失 - Cloudflare HTTPS跳转UTM参数丢失解决:CDN层跳转导致UTM丢失的排查和修复方案

## 总结

本文介绍了三套UTM参数自动巡检方案:

1. 基础版:适合快速上手,用`curl -L -w url_effective`检测最终URL是否保留UTM 2. 进阶版:适合排查问题,用`curl -I -L`逐层追踪重定向链路,精准定位UTM丢失位置 3. 生产级:适合正式部署,整合批量检测、CSV报告、定时执行、异常告警,真正实现无人值守

核心要点: - 用`url_effective`获取最终跳转地址 - 用`num_redirects`获取跳转次数 - 用`curl -I -L`逐层查看Location头 - 用crontab实现定时自动巡检 - 异常超过阈值自动告警

把这套脚本部署上去,你的营销链接UTM参数追踪就能实现真正的自动化,再也不用手工一个个检查了。

> 温馨提示:脚本中的邮件告警功能需要系统配置好mail命令。如果需要更强大的告警(钉钉、企业微信、Slack等),可以参考我的其他文章关于curl重定向告警的配置实战。

版权声明

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

发表评论