The watch Command Explained: Rerunning Commands on Repeat
Half of Linux administration is running the same command every few seconds to see whether something changed: is the copy finished, did the service come back, is the disk still filling. watch automates exactly that loop. Give it any command and it reruns it on an interval, painting the latest output on a full-screen display.
Basic usage
watch df -h
Every two seconds, df -h runs again and the screen updates. The header shows the interval, the command, and the current time. Ctrl+C exits.
Change the interval with -n:
watch -n 5 df -h # every 5 seconds
watch -n 0.5 ss -s # twice a second
The killer flag: -d
-d highlights every character that differs from the previous run:
watch -d free -h
Suddenly the numbers that are moving stand out from the wall of digits that are not. This is the difference between staring at output and actually seeing change. -d=permanent keeps anything that has ever changed highlighted, useful for catching a value that changes once, briefly, while you look away.
Quoting pipelines
watch hands your command to sh -c, so pipelines work, but quote them as one argument or your interactive shell will split the pipeline at the pipe and only the first part runs under watch:
# Correct: the whole pipeline reruns each interval
watch -n 2 'ss -t state established | wc -l'
# Also correct: counting matching processes
watch 'ps aux | grep -c [n]ginx'
The [n]ginx bracket trick keeps grep from matching its own process entry, an old idiom that pairs naturally with watch.
Everyday examples
# Watch a download or copy grow
watch -d ls -lh /var/backups/dump.sql.gz
# Watch a directory fill or empty
watch -n 1 'ls /var/spool/postfix/deferred | wc -l'
# Watch disk usage during a cleanup
watch -d df -h /
# Follow RAID rebuild progress
watch -n 10 cat /proc/mdstat
# Watch temperature under load
watch -n 1 sensors
# Watch for a host to come back after reboot
watch -n 2 'ping -c1 -W1 server01 >/dev/null && echo UP || echo DOWN'
# Watch systemd service state settle
watch -n 1 'systemctl status myapp --no-pager | head -12'
The /proc/mdstat case is a classic: RAID rebuilds report progress as a percentage in a file, and watch turns that file into a progress display with zero extra tooling.
Exiting on change with -g
-g flips watch from a monitor into a crude wait-for-event tool: it exits as soon as the output differs from the first run.
# Block until a file appears in the directory
watch -g ls /tmp/incoming && notify-send "file arrived"
# Wait for a DNS record to change
watch -n 30 -g dig +short example.com
Chained with &&, this gives you “run something when the observed thing changes” without writing a loop.
Errors and flickering
-e freezes the display on the first non-zero exit code so the error does not get overwritten by the next refresh, and -b beeps instead. For commands whose output takes long enough to produce that the screen visibly redraws in stages, -x executes the command directly rather than through sh -c, which can help, and keeping intervals realistic (do not run a 3-second command on a 1-second interval) helps more.
What watch is not
watch has no memory: it shows the current output and, with -d, one step of history. It does not log, graph, or alert. It is the right tool for the ten minutes you spend actively watching a rebuild, a deploy, or a filling disk, and the wrong tool for anything that should be watched while you are not there. For that, the monitoring stack (Netdata, Prometheus, or even a cron job appending to a log) picks up where watch stops.
Frequently Asked Questions
What does the watch command do?
watch runs a command repeatedly at a fixed interval, two seconds by default, and displays the most recent output on a full-screen refresh. It turns any one-shot command into a live view.
How do I change the watch refresh interval?
Use -n followed by seconds, for example watch -n 5 df -h for a five-second interval. Sub-second intervals like -n 0.5 are supported on modern versions.
What does watch -d do?
The -d flag highlights the characters that changed since the previous run, which makes slow-moving differences jump out. With -d=permanent, anything that has ever changed stays highlighted.
Why does my pipeline behave oddly under watch?
watch passes your command to sh -c, so pipes, quotes, and variables are re-evaluated in that shell. Quote the whole pipeline so your interactive shell does not expand parts of it first.
How do I stop watch?
Press Ctrl+C. watch runs until interrupted. With the -g flag it can instead exit automatically when the command output changes.
Should I use watch or a real monitoring tool?
watch is for ad-hoc, short-lived observation during active work. For continuous monitoring with history and alerting, use proper tools like Netdata or Prometheus; watch shows only the present moment.