watch命令的-d参数仅高亮字符位置差异,无法精准标出数值跳变;需用stat取字节数配合脚本缓存计算差值,并用tput着色实现↑红色增量、↓黄色减量、绿色无变化的精准监控。

watch 命令本身不能高亮“体积跳变”(比如从 1024KB 突增到 3276KB),它只支持 -d 参数高亮“前后两次输出中字符位置的差异”,对数值型变化不敏感——例如 ls -lh file.txt 输出里文件大小字段换了行、对齐偏移或单位变了(B → KB),-d 可能高亮整块区域,但无法精准标出“+2252KB”这种增量。
用 -d 高亮基础体积变动(适合粗粒度观察)
这是最简方式,适用于快速确认文件是否被写入:
-
watch -d 'ls -lh /path/to/logfile | awk '\''{print $5, $9}'\''
只提取大小和文件名,减少干扰;-d 会高亮大小字段(如1.2K→4.8K)的位置变化 -
watch -d 'stat -c "%s %n" /path/to/file'
用字节数(%s)替代人类可读格式,避免单位切换导致的错位,-d 对纯数字变化更稳定 - 注意:若文件名含空格或特殊字符,
awk '{print $5, $9}'可能截断,建议改用stat -c "%s %n"或du -b
用脚本实现真正的“跳变高亮”(推荐用于精准监控)
要让“增长 2MB”以红色突出、“减小 512B”以黄色标出,必须自己缓存上一次大小、计算差值、用 tput 上色:
- 先设初始值:
last_size=0 - 每轮执行:
curr_size=$(stat -c "%s" /path/to/file 2>/dev/null) - 比较并着色:
– 差值 > 0 →tput setaf 1(红)显示 “↑ +$(($curr_size - $last_size)) B”
– 差值 tput setaf 3(黄)显示 “↓ $(($last_size - $curr_size)) B”
– 无变化 →tput setaf 2(绿)显示当前大小 - 完整示例(每 3 秒刷新):
last=0; while :; do curr=$(stat -c "%s" /tmp/test.log 2>/dev/null); if [ -n "$curr" ]; then diff=$((curr - last)); if [ $diff -gt 0 ]; then echo "$(tput setaf 1)↑ +$diff B$(tput sgr0) — $(tput setaf 2)$curr B$(tput sgr0)"; elif [ $diff -lt 0 ]; then echo "$(tput setaf 3)↓ ${diff#-} B$(tput sgr0) — $(tput setaf 2)$curr B$(tput sgr0)"; else echo "$(tput setaf 2)$curr B$(tput sgr0)"; fi; last=$curr; else echo "$(tput setaf 7)file missing$(tput sgr0)"; fi; sleep 3; done
避坑要点:终端与精度
直接复制脚本前,请确认:
- 开头加
export TERM=xterm-256color,否则tput setaf可能失效 - 不要用
ls -lh提取大小——单位(B/KB/MB)切换会导致字符串长度突变,干扰差值判断;坚持用stat -c "%s"或du -b - 如果文件可能被清空或删除,
2>/dev/null和空值判断([ -n "$curr" ])必不可少,否则脚本会因 stat 报错中断 - 高频监控(如
sleep 0.5)慎用,尤其在机械硬盘或 NFS 路径上,stat 调用本身有开销
不复杂但容易忽略。-d 能帮你“看见变没变”,而自定义脚本才能告诉你“怎么变、变了多少”。











