shell 命令行组合逐段解释

curl -sL --max-time 15 https://dict.want.biz/ -o /tmp/live.html && diff /tmp/live.html dict.html | head -30 && echo "===差异行数===" && diff /tmp/live.html dict.html | grep -c "^[<>]"

这是一条 shell 命令行组合,作用是把线上页面拉下来和本地文件做差异对比。拆开逐段解释:

逐段含义

| 片段 | 作用 |

|---|---|

| curl -sL --max-time 15 https://dict.want.biz/ -o /tmp/live.html | 用 curl 下载线上页面,保存到 /tmp/live.html |

| && | 前一条命令成功(退出码 0)才执行下一条 |

| diff /tmp/live.html dict.html | 比较线上文件和本地 dict.html 的差异 |

| \| head -30 | 只显示差异输出的前 30 行 |

| && echo "===差异行数===" | 打印分隔标题 |

| && diff ... \| grep -c "^[<>]" | 统计差异行数 |

curl 参数

  • -s:静默模式,不显示进度条和错误(配合 -S 才会显示错误,这里没加)

  • -L:跟随重定向(301/302 会继续跟到最终地址)

  • --max-time 15:整个请求最长 15 秒,超时自动中断

  • -o /tmp/live.html:输出到指定文件,而不是打印到屏幕

diff 输出格式

diff 默认输出三种标记:

  • a(add):在第一个文件里新增

  • d(delete):在第一个文件里删除

  • c(change):两者都有但内容不同

实际内容行前面会带:

  • < 开头:来自第一个文件(/tmp/live.html,即线上)

  • > 开头:来自第二个文件(dict.html,即本地)

  • ---:分隔两个文件的内容块

所以 grep -c "^[<>]" 统计的就是真正有差异的内容行数(不含 --- 分隔线和行号标记)。

这条命令的实用场景

结合你的项目,这大概率是用于:

  1. 部署验证:把线上 dict.want.biz 的页面和本地构建产物 dict.html 对比,确认部署是否生效、有没有 CDN 缓存导致内容不一致。

  2. CDN 缓存排查:如果 -L 跟到了 Cloudflare 的边缘节点,diff 出的差异可以判断是缓存旧版本还是源站问题。

  3. 回归检查:每次改动后跑一遍,看线上和本地是否同步。

几个可以改进的点

  • -s 没有配 -S:如果 curl 失败(如 DNS 解析失败、超时),你会看不到任何错误信息,&& 直接短路,后面的 diff 也不会执行。建议改成 -sSL

  • --max-time 15 偏短:如果走 Cloudflare 且源站冷启动,15 秒可能不够,可考虑 --connect-timeout 5 --max-time 30

  • diff 执行了两次:一次取前 30 行,一次统计行数,等于把同一个 diff 跑了两遍。可以改成先存到变量或临时文件:

  
curl -sSL --max-time 30 https://dict.want.biz/ -o /tmp/live.html \
  
  && diff /tmp/live.html dict.html > /tmp/diff.txt \
  
  && head -30 /tmp/diff.txt \
  
  && echo "===差异行数===" \
  
  && grep -c "^[<>]" /tmp/diff.txt
  
  • 想忽略空白差异:如果只想看实质性内容变化,可以加 -w(忽略所有空白)或 -b(忽略空白量变化):
  
diff -w /tmp/live.html dict.html
  

如果你是在排查 dict.want.biz 线上和本地不一致的问题,把这条命令的实际输出贴出来,我可以帮你判断差异是来自 CDN 缓存、构建产物不同步,还是页面里有动态内容(如时间戳、随机 token)导致的正常噪声。