watch runs a command every N seconds and displays the output. It’s the simplest form of real-time monitoring — no setup, no configuration, just instant feedback loops.

Basic Usage

1
2
3
4
5
6
7
8
# Run command every 2 seconds (default)
watch date

# Run every 5 seconds
watch -n 5 date

# Run every 0.5 seconds
watch -n 0.5 date

Highlight Changes

1
2
3
4
5
# Highlight differences between updates
watch -d df -h

# Highlight changes permanently (cumulative)
watch -d=cumulative df -h

Common Options

1
2
3
4
5
6
7
-n, --interval    Seconds between updates (default: 2)
-d, --differences Highlight changes
-t, --no-title    Hide the header
-b, --beep        Beep on command error
-e, --errexit     Exit on command error
-c, --color       Interpret ANSI color sequences
-x, --exec        Pass command to exec instead of sh -c

Practical Examples

Disk Space

1
2
3
4
5
6
7
8
# Watch disk usage
watch df -h

# Watch specific mount
watch 'df -h | grep /dev/sda1'

# Watch directory size
watch 'du -sh /var/log'

Memory

1
2
3
4
5
# Memory stats
watch free -h

# Memory with buffers/cache detail
watch 'free -h && echo && cat /proc/meminfo | head -10'

Processes

1
2
3
4
5
6
7
8
# Process count
watch 'ps aux | wc -l'

# Specific process
watch 'ps aux | grep nginx'

# Process memory
watch 'ps aux --sort=-%mem | head -10'

Network

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Network connections
watch 'netstat -tuln'

# Connection count
watch 'netstat -an | wc -l'

# Active connections
watch 'ss -s'

# Interface stats
watch 'cat /proc/net/dev'

Files and Directories

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# File list
watch ls -la

# Directory size changes
watch 'du -sh *'

# File count
watch 'find . -type f | wc -l'

# Recent files
watch 'ls -lt | head -10'

Docker

1
2
3
4
5
6
7
8
# Container status
watch docker ps

# Container stats
watch 'docker stats --no-stream'

# Image list
watch docker images

Kubernetes

1
2
3
4
5
6
7
8
# Pod status
watch kubectl get pods

# All resources
watch 'kubectl get pods,svc,deploy'

# Pod logs (last 5 lines)
watch 'kubectl logs -l app=myapp --tail=5'

Git

1
2
3
4
5
6
7
8
# Branch status
watch git status

# Log (one line per commit)
watch 'git log --oneline -10'

# Diff stats
watch git diff --stat

Logs

1
2
3
4
5
6
7
8
# Last log lines
watch 'tail -5 /var/log/syslog'

# Error count
watch 'grep -c ERROR /var/log/app.log'

# Recent errors
watch 'grep ERROR /var/log/app.log | tail -5'

APIs and Services

1
2
3
4
5
6
7
8
# HTTP health check
watch 'curl -s localhost:8080/health'

# API response time
watch 'curl -s -w "%{time_total}\n" -o /dev/null http://localhost/api'

# Service status
watch systemctl status nginx

Database

1
2
3
4
5
6
7
8
# PostgreSQL connections
watch 'psql -c "SELECT count(*) FROM pg_stat_activity"'

# MySQL process list
watch 'mysql -e "SHOW PROCESSLIST"'

# Table row count
watch 'psql -c "SELECT count(*) FROM users"'

Quoting and Complex Commands

For commands with pipes or special characters, quote the entire command:

1
2
3
4
5
6
7
8
# Single quotes (preferred)
watch 'ps aux | grep nginx | wc -l'

# Double quotes (allows variable expansion)
watch "df -h | grep $MOUNT"

# Multiple commands
watch 'echo "=== Disk ===" && df -h && echo "=== Memory ===" && free -h'

Using with –exec

For commands with their own arguments:

1
2
3
4
5
# Without exec: may have quoting issues
watch ls -la /tmp

# With exec: cleaner
watch -x ls -la /tmp

Exit Conditions

1
2
3
4
5
6
7
8
# Exit when command fails
watch -e 'curl -f http://localhost/health'

# Beep on error (non-zero exit)
watch -b 'systemctl is-active myservice'

# Exit when output changes (use with diff)
watch -g 'cat /etc/passwd | md5sum'

Combining with Other Tools

With grep for filtering

1
watch 'dmesg | tail -20 | grep -i error'

With awk for formatting

1
watch "free | awk '/Mem:/ {printf \"%.1f%%\n\", \$3/\$2*100}'"

With jq for JSON

1
watch 'curl -s localhost:8080/metrics | jq .requests_total'

Alternatives

while loop

1
2
3
4
5
6
while true; do
    clear
    date
    df -h
    sleep 2
done

viddy (modern watch)

1
2
3
4
5
6
# Install
brew install viddy  # macOS
go install github.com/sachaos/viddy@latest

# Use (better diff, time machine, etc.)
viddy -d df -h

entr (run on file change)

1
2
3
4
5
# Run command when files change
ls *.py | entr python test.py

# Clear screen and run
ls *.py | entr -c python test.py

Tips

Disable Title for Clean Output

1
watch -t 'date +%H:%M:%S'

Use Color Output

1
2
watch -c 'ls --color=always'
watch -c 'grep --color=always ERROR /var/log/app.log | tail -10'

Precision Timing

1
2
# Exact intervals (compensates for command runtime)
watch -p -n 1 date +%s.%N

Redirect Output

1
2
# Can't redirect watch output directly, but can log the command
watch 'df -h | tee -a disk.log'

Quick Reference

OptionPurpose
-n NInterval in seconds
-dHighlight differences
-tNo title/header
-cInterpret colors
-eExit on error
-bBeep on error
-gExit when output changes
-xUse exec instead of shell

watch is deceptively simple. No dashboards, no configuration — just watch <command> and you have real-time monitoring. It’s the first tool I reach for when I need to see something change over time.