Linux watch: Repeating Commands Periodically
The `watch` command is one of those Unix utilities that seems deceptively simple until you realize how much time it saves. Instead of repeatedly hammering the up arrow and Enter key to re-run a...
Key Insights
- The
watchcommand executes a command repeatedly at fixed intervals (default 2 seconds), making it essential for monitoring system state without writing custom scripts. - Use
-dto highlight differences between iterations and-nto customize intervals—combining these flags transforms watch into a powerful change-detection tool for deployments and debugging. - Quote complex commands properly: single quotes for literal strings, double quotes when you need variable expansion, and escape dollar signs when you want watch to evaluate them each iteration.
Introduction to the watch Command
The watch command is one of those Unix utilities that seems deceptively simple until you realize how much time it saves. Instead of repeatedly hammering the up arrow and Enter key to re-run a command, watch does it for you automatically, displaying the output in a clean, updating interface.
At its core, watch executes a command at regular intervals and displays the results. The screen updates in place, so you get a real-time view of changing data. This makes it invaluable for monitoring system resources, tracking deployment progress, observing log files, and debugging issues where timing matters.
The basic syntax is straightforward:
watch [options] command
Here’s the simplest possible example:
watch date
This displays the current date and time, updating every two seconds. You’ll see a header showing the interval, the command being executed, and the current time. Press Ctrl+C to exit.
Basic Usage and Syntax
When you run watch, it clears the screen and displays three pieces of information at the top:
- The update interval (default: 2.0 seconds)
- The command being executed
- The current timestamp
Below that, you see the command’s output, which refreshes at the specified interval. The default two-second refresh is a reasonable balance between responsiveness and system load.
Let’s look at practical examples:
watch date
This shows the current date and time updating every two seconds. Simple, but it demonstrates the core behavior.
For something more useful, monitor disk usage:
watch df -h
This displays your filesystem usage, updating continuously. You can watch disk space decrease as you download files or run builds.
Monitor memory usage:
watch free -m
This shows memory and swap usage in megabytes. It’s particularly useful when you’re running memory-intensive operations and want to ensure you’re not hitting swap.
The output remains stable on screen—only the changing values update. This makes it easy to spot trends and anomalies.
Essential Options and Flags
The watch command becomes significantly more powerful with a few key flags.
Custom Intervals with -n
The -n flag sets the update interval in seconds:
watch -n 5 uptime
This updates every five seconds instead of two. Use longer intervals for commands that are expensive to run or when you don’t need rapid updates. Use shorter intervals (down to 0.1 seconds) when monitoring fast-changing data:
watch -n 0.5 'ps aux | grep nginx | wc -l'
Highlighting Differences with -d
The -d flag highlights what changed since the last iteration:
watch -d 'ls -l /var/log'
Changed values appear in reverse video (usually highlighted). This is incredibly useful when you’re waiting for a specific file to appear or for a value to change.
Removing the Header with -t
The -t flag removes the header, giving you a cleaner output:
watch -t df -h
This is useful when piping output or when the header is distracting.
Precise Intervals with -p
The -p flag attempts to run the command at precise intervals, accounting for command execution time:
watch -p -n 1 'date +%s.%N'
Without -p, if your command takes 0.3 seconds to run, a 1-second interval means 1.3 seconds between starts. With -p, watch tries to maintain exactly 1 second between executions.
Combine flags for maximum utility:
watch -n 1 -d 'ps aux | grep python | grep -v grep'
This monitors Python processes every second and highlights any changes—perfect for debugging process spawning or crashes.
Practical Real-World Scenarios
Here’s where watch shines in actual development and operations work.
Monitoring Log File Growth
watch 'tail -n 20 /var/log/syslog'
This shows the last 20 lines of syslog, updating continuously. You see new log entries appear in real-time. It’s more convenient than tail -f when you want to see a fixed window of recent entries.
Tracking Deployment Progress
watch 'kubectl get pods -n production'
When deploying to Kubernetes, this shows pod status updates. You can watch pods transition from Pending to Running, or catch CrashLoopBackOff errors immediately.
For Docker Compose:
watch 'docker-compose ps'
Observing Network Connections
watch -n 2 'netstat -tuln | grep LISTEN'
This displays listening ports on your system. Useful when starting services to verify they’re binding to the correct ports.
For active connections:
watch -n 1 'netstat -an | grep ESTABLISHED | wc -l'
This counts active connections, helping you monitor connection pool usage or detect connection leaks.
Monitoring Directory Changes
watch 'ls -lh /tmp/uploads | tail -n 10'
This shows the newest files in a directory. Perfect for monitoring upload directories or build output folders.
Tracking Build Progress
watch 'du -sh /var/lib/docker'
Monitor Docker’s disk usage during builds. Combine with -d to highlight when the size changes:
watch -d -n 5 'du -sh /var/lib/docker'
Monitoring System Resources
watch -n 1 'ps aux | sort -nrk 3,3 | head -n 5'
This shows the top 5 processes by CPU usage, updating every second. Essential for identifying CPU hogs.
For memory:
watch -n 1 'ps aux | sort -nrk 4,4 | head -n 5'
Advanced Techniques and Gotchas
Quoting Requirements
Complex commands need proper quoting. Use single quotes to pass the entire command as-is:
watch 'ps aux | grep nginx | grep -v grep'
Without quotes, watch only monitors ps aux, and the shell interprets the pipes before watch sees them.
Use double quotes when you need variable expansion at watch startup:
USER=$(whoami)
watch "ps aux | grep $USER"
But be careful—this expands $USER once when you run watch, not on each iteration.
Variable Expansion per Iteration
To expand variables on each iteration, escape the dollar sign:
watch "echo \$RANDOM"
This generates a new random number each time. Without the backslash, $RANDOM expands once when you start watch.
Complex Piping and Sorting
You can build sophisticated monitoring commands:
watch 'ps aux | awk "{print \$3, \$11}" | sort -rn | head -n 5'
This shows the top 5 processes by CPU with just their CPU percentage and command name. Note the escaped dollar signs in the awk command.
Exit on Change with -g
The -g flag exits when output changes:
watch -g 'pgrep myapp'
This runs until myapp appears or disappears, then exits. Useful in scripts:
watch -g 'test -f /tmp/deployment.complete' && echo "Deployment finished!"
Performance Considerations
Be mindful of command execution time. If your command takes 3 seconds to run but you set a 1-second interval, watch will run continuously without pausing. This can overload your system.
For expensive commands, use longer intervals:
watch -n 10 'find /var/log -type f -size +100M'
Exit Codes
Watch returns the exit code of the last command execution. You can use this in scripts:
if watch -g -n 1 'pgrep -f "my-service"'; then
echo "Service stopped"
fi
Alternatives and When Not to Use watch
While watch is excellent for interactive monitoring, it’s not always the right tool.
For File Changes: entr
The entr utility is better for reacting to file changes:
ls *.py | entr pytest
This runs tests whenever Python files change—more efficient than polling with watch.
For Scheduled Tasks: cron
Use cron for periodic execution that doesn’t need interactive display:
*/5 * * * * /usr/local/bin/backup.sh
Custom Shell Loops
Sometimes a while loop is more appropriate:
while true; do
date
sleep 2
done
This is equivalent to watch date, but you have more control over output formatting and error handling. However, it doesn’t clear the screen or provide the clean interface watch offers.
When to Use What
- Use
watchfor interactive monitoring where you want to see updates in place - Use
entrfor file-change triggered actions - Use cron for scheduled background tasks
- Use while loops when you need complex logic between iterations
The watch command excels at its specific purpose: providing a clean, updating view of command output. Master it, and you’ll find yourself using it daily for debugging, monitoring, and understanding system behavior in real-time.