Updated: 4 November 2026 · Applies to: watch from procps-ng 4.0.4 on Ubuntu 26.04 and 24.04, Debian 13 and AlmaLinux 10 (procps-ng 3.3.17 on AlmaLinux 9); Bash loops and systemd timers tested on Ubuntu 26.04

To run a Linux command again and again every few seconds, use the watch command: watch -n 5 COMMAND runs COMMAND every 5 seconds and redraws its output on a clean screen until you press Ctrl+C. Without -n, watch repeats the command every 2 seconds. If you need normal scrolling output, a log file or a job that keeps running after you log out, use a while loop with sleep, or a systemd timer when it must also survive a reboot. Cron does not help here: its smallest step is one minute.

How to use the watch command

  1. Type watch followed by the command you want to repeat:
    watch free -m
  2. watch clears the screen, runs the command and shows a header with the interval, the command, the host name and the time. This is lab output from our Ubuntu 26.04 test container (the memory figures belong to the test machine):
    Every 2.0s: free -m                                                    vps: Sat Oct 10 13:35:05 2026
                   total        used        free      shared  buff/cache   available
    Mem:            3818         953         226          71        2993        2865
    Swap:           1199           6        1193
  3. The screen refreshes in place every 2 seconds. Press Ctrl+C to stop; watch then exits with status 0.

watch is part of the procps package (procps-ng on AlmaLinux, Rocky Linux and RHEL). It was already present in the Ubuntu 24.04 and 26.04 images we tested, but not in the minimal AlmaLinux 9 and 10 or Debian 13 container images. If your server does not have it:

sudo apt install procps        # Ubuntu, Debian
sudo dnf install procps-ng     # AlmaLinux, Rocky Linux, RHEL, Fedora

Set the interval with -n

watch -n 5 uptime
watch -n 0.5 df -h /

The interval is in seconds and may be a fraction. watch does not go below 0.1 seconds: when we ran watch -n 0.01 date, the header showed Every 0.1s: date. According to the watch manual, the WATCH_INTERVAL environment variable sets your own default; with WATCH_INTERVAL=5 our test header read Every 5.0s.

Commands with pipes, quotes and aliases

watch hands the command to sh -c. Put anything with a pipe, a redirect or a semicolon in single quotes, so the whole line runs on every update:

watch -n 1 'ls /etc | wc -l'

Without the quotes, your own shell takes the pipe and sends the output of watch itself to wc. Aliases and shell functions are not available inside sh -c: in our test watch ll only showed sh: 1: ll: not found, so write the full command (ls -l). With -x, watch runs the command directly without a shell, which saves quoting for simple commands: watch -x ls -l /var/log.

Highlight what changed with -d

watch -d -n 1 'ss -tn state established'

-d (--differences) shows the characters that changed since the previous update in reverse video. In our test with watch -d date +%S, only the digit that changed was highlighted. --differences=permanent keeps highlighting everything that has changed since the first run.

Let watch stop by itself: -g, -e and -q

  • -g (--chgexit): exit as soon as the output changes. Handy for waiting on a file, a DNS change or a service, and you can chain the next command. In our test, watch -g -n 1 'ls /tmp/flag 2>&1' exited with status 0 once we created the file:
    watch -g -n 10 'dig +short example.com' && echo "DNS answer changed"
    According to the manual, only changes in the visible part of the screen count.
  • -e (--errexit): freeze the screen when the command fails. Our test showed command exit with a non-zero status, press a key to exit, and after a key press watch exited with status 8.
  • -q N (--equexit): exit when the output has not changed for N updates, for example when a copy has finished growing. It exists in procps-ng 4.x (Ubuntu 24.04 and 26.04, Debian 13, AlmaLinux 10) but not in AlmaLinux 9’s 3.3.17.
  • -b (--beep): beep when the command returns a non-zero exit status.

Other options: -t hides the header line, -p tries to start the command at exact intervals, -c shows ANSI colours, -w turns off line wrapping and, in procps-ng 4.x, -r stops watch from re-running the command when you resize the window.

Practical examples

  • Free disk space while a backup runs: watch -n 10 df -h /
  • Size of a file that is being copied or downloaded: watch -n 1 'ls -lh /root/backup.tar.gz'
  • Number of open TCP connections: watch -n 2 'ss -tn state established | wc -l' (more in watch TCP and UDP ports in real time)
  • Busiest processes: watch -n 2 'ps aux --sort=-%cpu | head -n 6', or use top as in how to list running processes
  • Memory, uptime and load: watch -n 5 'free -m; uptime'

To follow a log file line by line, tail -f is a better fit than watch.

Repeat a command without watch: Bash loops

watch takes over the screen. When you want each result kept on its own line, or the repeat inside a script, combine a loop with sleep:

for i in {1..3}; do echo "Run $i: $(date +%T)"; sleep 5; done

Output from our test:

Run 1: 13:36:22
Run 2: 13:36:27
Run 3: 13:36:32

To repeat forever, until you press Ctrl+C:

while true; do date +%T; sleep 2; done

To repeat until something is true, such as a file appearing:

until [ -f /tmp/ready ]; do echo "waiting..."; sleep 2; done; echo "ready"

A loop waits for the command to finish before it sleeps, so a command that takes 3 seconds plus sleep 5 repeats every 8 seconds. The sleep command guide covers minutes, hours and fractions.

Keep it running after you log out

Start the loop with nohup and &, writing to a file, then stop it later with kill and the process ID that the shell prints:

nohup bash -c 'while true; do date +%T >> /tmp/ticks.log; sleep 2; done' >/dev/null 2>&1 &

In our test the log gained a line every 2 seconds. To keep an interactive watch screen alive after you disconnect, run it inside tmux or screen.

Every 30 seconds, also after a reboot: a systemd timer

For a permanent job that runs more often than once a minute, use a systemd timer instead of cron. Create /etc/systemd/system/disk-check.service:

[Unit]
Description=Log disk usage

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'df -h / >> /var/log/disk-check.log'

and /etc/systemd/system/disk-check.timer with the same name:

[Unit]
Description=Run disk-check every 30 seconds

[Timer]
OnBootSec=30s
OnUnitActiveSec=30s
AccuracySec=1s

[Install]
WantedBy=timers.target

Then enable it and check the next run:

sudo systemctl daemon-reload
sudo systemctl enable --now disk-check.timer
systemctl list-timers disk-check.timer

According to the systemd manual, AccuracySec defaults to 1 minute, which is why it is set to 1 second here. systemd-analyze verify accepted both files on Ubuntu 26.04; our container had no running systemd, so we checked the files but did not start the timer. For fixed clock times use OnCalendar=*:*:0/30 instead; systemd-analyze calendar '*:*:0/30' showed the next runs at :00 and :30 of each minute.

For jobs that run once a minute or less often, cron is simpler: see how to add jobs to cron and how to read crontab syntax.

Related services

KVM VPS hosting

NVMe SSD and full root access, with Free Basic Managed Support.

Unmanaged dedicated servers

full root access and free IPMI KVM, with Free Basic Managed Support.

Managed dedicated servers

our engineers look after the server for you, from $135 a month.

Was this answer helpful?

Still stuck? Open a ticket