533 字
3 分钟
Linux `watch` 的 2 秒间隔,原来是“执行完再等 2 秒”
今天才注意到一个很容易被 watch 顶部那句 Every 2.0s 误导的细节:
watch some-commandwatch 的默认间隔就是 2 秒。
但它默认的逻辑并不是:
0s 2s 4s 6s| run | run | run | run而更接近:
run commandwait command exitssleep 2srun command again也就是说,如果命令本身执行需要 0.8 秒,那么两次启动之间大约是:
0.8s + 2.0s = 2.8s如果命令需要 5 秒,那就大约每 7 秒才启动一次。
这不是猜测。procps-ng 的 watch(1) 手册对 -p, --precise 的描述已经把两种行为区分得很明确:默认情况下,下一次执行发生在上一次执行完成后的 interval 秒;加上 --precise 后,才按照上一次执行开始的时间计算周期。
源码里的主循环逻辑也很直接:
if (run_command(command, command_argv)) break;
if (precise_timekeeping) { ...} else { usleep(interval * USECS_PER_SEC);}也就是先同步执行完命令,普通模式随后直接 sleep(interval)。
所以直接写:
watch some-command并不代表:
每隔 2 秒启动一次
some-command
更准确的理解是:
每次
some-command执行结束后,再等默认的 2 秒,然后开始下一次。
如果真正想要“每 2 秒一个时间点”这种更接近固定周期的行为,可以使用:
watch -p some-command因为默认 interval 本来就是 2 秒,所以这里也不需要额外写 -n 2。
假设命令运行 0.8 秒,那么 watch 会再等大约 1.2 秒,从而尽量保持:
0s 2s 4s 6s| run | run | run | run当然,如果命令自己就执行了 5 秒,而周期是 2 秒,watch 也不会并发启动多份命令。它仍然会等当前命令结束,只是下一次会尽量按照 precise 模式的时间计算方式继续运行。
所以这其实就是 scheduler 里很经典的两种语义:
普通 watchfixed-delay
watch -pfixed-rate / fixed-periodwatch 顶部显示的 Every 2.0s,严格来说有点容易让人产生误解。默认行为其实是:
任务之间至少间隔 2 秒,而不是任务每隔 2 秒准时启动。
Linux `watch` 的 2 秒间隔,原来是“执行完再等 2 秒”
https://blog.lishuyu.app/posts/2026-09-07-linux-watch-default-2s-after-command-finishes/