How to Use inotifywait and inotifywatch to Monitor File System Events in Real Time on Linux

Monitoring file system changes in real time is essential for tasks ranging from automated build pipelines and log rotation to security auditing and configuration management. While polling-based approaches like watch or periodic find scans work, they are inefficient, resource-hungry, and introduce latency between the actual change and its detection.

The inotify subsystem in the Linux kernel provides an efficient, event-driven mechanism for monitoring file system events. The inotifywait and inotifywatch command-line utilities from the inotify-tools package expose this subsystem to shell scripts and terminal workflows, enabling you to react to file system changes the instant they occur.

What Is inotify and How Does It Work?

The inotify API is a Linux kernel subsystem that allows user-space applications to subscribe to file system events on specific files or directories. Unlike polling, which repeatedly checks the state of files at fixed intervals, inotify uses a push-based model — the kernel notifies your application the moment an event occurs.

This approach has several advantages:

  • Zero CPU overhead between events — your process sleeps until the kernel wakes it with an event notification.
  • Immediate detection — events are delivered within microseconds of the file system operation.
  • Granular event types — you can subscribe to specific events such as creation, deletion, modification, access, attribute changes, and more.

The inotify-tools package provides two utilities that wrap the kernel inotify API for command-line use:

  • inotifywait — waits for specific events and outputs them to standard output, making it ideal for scripting and automation.
  • inotifywatch — collects file system event statistics over a period of time and presents them in a summary table.

Installing inotify-tools

The inotify-tools package is available in the default repositories of most major Linux distributions.

Debian, Ubuntu, and Derivatives

sudo apt update
sudo apt install inotify-tools

Fedora, RHEL, and CentOS Stream

sudo dnf install inotify-tools

Arch Linux and Manjaro

sudo pacman -S inotify-tools

openSUSE

sudo zypper install inotify-tools

Verify the installation by running:

inotifywait --help

Using inotifywait to Monitor File System Events

Basic Usage — Watching a Single File

The simplest use of inotifywait monitors a single file for any event:

inotifywait /path/to/file.txt

This command blocks until a file system event occurs on file.txt, then prints the event and exits. For example, if another process modifies the file, you might see:

/path/to/file.txt MODIFY

Watching a Directory

To monitor all events in a directory:

inotifywait /var/log/

This watches the directory itself for events such as new files being created or existing files being deleted. However, it does not watch the contents of files within the directory by default.

Recursive Monitoring

To monitor a directory and all its subdirectories recursively, use the -r flag:

inotifywait -r /home/user/projects/

This sets up inotify watches on every subdirectory within the specified path. New subdirectories created after monitoring begins are also automatically watched.

Continuous Monitoring with the Monitor Flag

By default, inotifywait exits after the first event. To monitor continuously, use the -m (monitor) flag:

inotifywait -m /var/log/syslog

The command now runs indefinitely, printing every event as it occurs:

/var/log/syslog MODIFY
/var/log/syslog MODIFY
/var/log/syslog ACCESS

Filtering Specific Events

The -e flag lets you subscribe to specific event types, reducing noise and focusing on the changes that matter to your workflow.

Available Event Types

  • access — a file was read.
  • modify — a file was written to.
  • attrib — file metadata changed (permissions, timestamps, extended attributes).
  • close_write — a file opened for writing was closed.
  • close_nowrite — a file opened for reading only was closed.
  • open — a file was opened.
  • moved_to — a file was moved into the watched directory.
  • moved_from — a file was moved out of the watched directory.
  • create — a new file or directory was created.
  • delete — a file or directory was deleted.
  • delete_self — the watched file or directory itself was deleted.
  • move_self — the watched file or directory itself was moved.

Monitoring Only File Modifications

inotifywait -m -e modify /etc/nginx/nginx.conf

Monitoring File Creation and Deletion

inotifywait -m -r -e create -e delete /var/www/html/

Monitoring Completed Write Operations

The close_write event is particularly useful for triggering actions after a file has been fully written, rather than reacting to each individual write operation:

inotifywait -m -e close_write /home/user/uploads/

Formatting Output for Scripting

The --format flag customises the output format, making it easier to parse in scripts. Available format specifiers include:

  • %w — the watched path.
  • %f — the filename (when watching a directory).
  • %e — the event type(s).
  • %T — the timestamp (requires --timefmt to define the format).

Example: Timestamped Output

inotifywait -m -r -e modify -e create -e delete \
  --timefmt '%Y-%m-%d %H:%M:%S' \
  --format '%T %w%f %e' \
  /var/log/

This produces output such as:

2026-11-05 09:15:32 /var/log/syslog MODIFY
2026-11-05 09:15:45 /var/log/auth.log MODIFY
2026-11-05 09:16:01 /var/log/cron.log CREATE

Practical Script Examples

Auto-Rebuild on Source Code Changes

This script watches a project’s source directory and triggers a build whenever a source file is saved:

#!/bin/bash
inotifywait -m -r -e close_write --include '\.(js|ts|css|html)$' /home/user/project/src/ |
while read -r directory event filename; do
    echo "Change detected: $filename ($event)"
    echo "Running build..."
    cd /home/user/project/ && npm run build
    echo "Build complete."
done

Automatic Log Compression

This script watches a log directory and compresses any new log files once they are fully written:

#!/bin/bash
inotifywait -m -e close_write --include '\.log$' /var/log/myapp/ |
while read -r directory event filename; do
    echo "Compressing $directory$filename"
    gzip "$directory$filename"
done

Security Audit — Monitoring Configuration File Changes

#!/bin/bash
inotifywait -m -r -e modify -e attrib -e delete \
  --timefmt '%Y-%m-%d %H:%M:%S' \
  --format '%T %w%f %e' \
  /etc/ >> /var/log/config-audit.log 2>&1 &

This runs in the background and appends every configuration file change to an audit log with timestamps.

Using inotifywatch for Event Statistics

While inotifywait is designed for real-time event processing, inotifywatch collects event statistics over a defined period and presents a summary table.

Basic Usage

inotifywatch -t 60 -r /var/log/

This monitors /var/log/ recursively for 60 seconds, then prints a table showing how many of each event type occurred on each file:

total  access  modify  close_write  filename
152    89      52      11           /var/log/syslog
34     12      18      4            /var/log/auth.log
8      3       4       1            /var/log/kern.log

Use Cases for inotifywatch

  • Identifying the busiest files in a directory tree during a specific time window.
  • Baselining normal I/O activity before and after a deployment or configuration change.
  • Detecting unexpected file access patterns that may indicate unauthorised activity.

Kernel Limits and Tuning

The inotify subsystem has kernel-level limits that control how many watches a single user can create. If you monitor large directory trees, you may encounter the error:

Failed to watch /path/to/dir; upper limit on inotify watches reached!

Checking Current Limits

cat /proc/sys/fs/inotify/max_user_watches

The default value is typically 8192 or 65536, depending on the distribution.

Increasing the Limit Temporarily

sudo sysctl fs.inotify.max_user_watches=524288

Making the Change Permanent

Add the following line to /etc/sysctl.conf or a file in /etc/sysctl.d/:

fs.inotify.max_user_watches=524288

Then reload the configuration:

sudo sysctl -p

Limitations of inotify

  • Does not work across network file systems — inotify monitors the local VFS layer. Changes made to NFS, CIFS/SMB, or other network-mounted file systems by remote clients are not detected.
  • No recursive watch inheritance on older kernels — while inotifywait -r handles this in user space, the kernel inotify API itself does not support recursive watches natively (unlike the newer fanotify API).
  • Event queue overflow — if events arrive faster than your script can process them, the kernel event queue may overflow, and events will be lost. The IN_Q_OVERFLOW event signals this condition.
  • Watch descriptor limits — each watched directory or file consumes a watch descriptor. Monitoring very large directory trees requires tuning the kernel limits as described above.

Despite these limitations, inotifywait and inotifywatch remain the most efficient and widely used tools for file system event monitoring in Linux shell scripting. For workloads that exceed inotify’s capabilities, consider the fanotify API or dedicated file integrity monitoring tools such as AIDE or OSSEC.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.