CLI tool
inotify-tools/inotify-tools avatar
inotify-tools/inotify-tools

inotify-tools: inotifywait and inotifywatch for shell scripts

inotify-tools is a library and a set of command-line programs providing a simple interface to inotify.

3,429 stars403 forksRustGPL-2.0

At a glance

What is it?
The package that turns Linux inotify into two command-line programs and a C library, now written in Rust with an ABI compatible libinotifytools.so. It fits shell scripts and small watchers; it is the wrong tool for recursive trees or high-rate event streams.
Who is it for?
Adopt inotify-tools when a shell script, a build step or a small daemon needs to react to file changes on one Linux box, and when the historical C ABI matters to something you already link against. Do not adopt it as a recursive filesystem crawler, as a cross-platform watcher, or as a replacement for an event pipeline that must survive a burst of thousands of writes per second; the tools expose one inotify instance's semantics and nothing above them.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What inotify-tools is for, and who ends up using it

Linux exposes filesystem notifications through the inotify API, which is a C interface: you create a watch descriptor, read events from a file descriptor, and manage a watch list yourself. That is fine inside a program and awkward inside a shell script. inotify-tools exists to close that gap. The README states the purpose plainly: the package allows inotify's features to be used from within shell scripts. It ships two command-line programs, inotifywait and inotifywatch, plus libinotifytools, a small library with a C API at <inotifytools/inotifytools.h> that the tools themselves use. The audience is therefore narrow and specific: people writing shell automation, build scripts, deployment hooks, log shippers and small watchers on Linux. If your program is already in C or Rust and can call inotify directly, the command-line layer adds a process boundary and a text parsing step you do not need. The fsnotifywait and fsnotifywatch names are documented as aliases of the same programs.

How inotifywait and inotifywatch split the work

The two programs answer different questions about the same kernel facility. inotifywait waits for or monitors filesystem events, which is the streaming case: it blocks, prints events as they arrive, and is meant to be read line by line by another process. inotifywatch gathers filesystem usage statistics, which is the counting case: it collects events over a period and reports totals, useful when you want to know which paths are hot rather than to react to a single change. Both are thin front ends over libinotifytools, which wraps watch setup, the event read loop and the text formatting. The README points to the man pages for the details of flags and output, and that is where the real interface lives; the README itself does not enumerate event names or output fields. One structural fact is worth knowing before you plan an upgrade: libinotifytools.so is described as a drop-in, ABI compatible replacement for the historical C library, with the same symbols, the same SONAME libinotifytools.so.0, and the same headers. That is why the Makefile still carries the libtool version-info 4:1:4 of the original library and installs SOFILE libinotifytools.so.0.4.1.

Building inotify-tools from source with make

The project is built with GNU make driving cargo, not with cargo alone. The README lists the requirements: Rust with cargo and rustc 1.63 or newer, GNU make, a C compiler used to generate the installed headers, and a C++ compiler for make check. The three commands below are the ones the README gives, in order. After make finishes, the binaries land under the cargo target directory and the headers and man pages are generated; make check runs the test suite, and make install places files under /usr/local by default. The Makefile documents the install layout variables, so a distribution-style install can override prefix, libdir, includedir and mandir, and DESTDIR is supported for staged packaging. ENABLE_SHARED and ENABLE_STATIC control which library forms are produced, and ALL_STATIC=1 builds the tools against a static library in its own target directory so the static and normal builds do not invalidate each other.

A first real use: watching a directory from a script

The README does not include a worked example, so the honest starting point is the man page for inotifywait, which the README names as the place to read further. What the repository does confirm is the shape of the interface: inotifywait monitors filesystem events and prints them, and the package exists so a shell script can consume that output. A typical pattern is to run it in the background or in a pipeline and branch on the lines it emits. Before writing that script, run the binary once by hand and look at the event names and fields your kernel actually produces, because those strings are what your case statement will match. The Makefile also exposes a build-time knob worth knowing about: PROFILE selects the cargo profile, so PROFILE=dev gives a debug build when you want symbols while developing a wrapper around the tools.

Where inotify-tools stops being the right answer

The main limitation is inherent to inotify rather than to this package: a watch is attached to a path, and the kernel does not recursively watch a tree for you. A script that wants to follow a deep directory has to add watches itself, and new subdirectories created after startup need new watches, which means the watcher must also react to its own control problem. There is a second, harder constraint. inotify events are delivered through a queue on a file descriptor, and a consumer that falls behind can lose events; the tools do not turn that into a durable log. If your workload is a burst of thousands of writes per second, or if an event must never be missed, this is the wrong layer. A third case: the package is Linux-only by construction, since inotify is a Linux API. The repository topics list c, fsnotify, inotify, inotify-tools, inotifywait, inotifywatch and linux, and nothing suggests a portable abstraction. If the same script must run on macOS or the BSDs, inotify-tools cannot be the mechanism.

fanotify and inotify are different questions

The natural alternative to reach for is fanotify, the other Linux notification interface. The difference in approach matters more than any feature list. inotify is per-path: you register interest in specific files and directories and receive events for them, which is exactly what a shell script wants and what makes inotifywait's output easy to parse. fanotify works at the filesystem or mount level and can gate access, which makes it the interface of choice for security and antivirus style tooling that must decide whether an operation is allowed to proceed. The cost is a heavier setup and a different permission model. Choosing inotify-tools means accepting per-path watches and no access control; choosing fanotify means accepting mount-scoped semantics and a more involved integration. Neither replaces the other, and a project that needs both usually ends up with two components rather than one.

Releases, packaging and the GPL-2.0 licence

The release model is unusual and affects upgrade cost. According to the README, every commit on master that passes all CI builds is released as <series>.<commit count>, for example 4.26.261, with a source tarball and static x86_64 and aarch64 Linux builds. The series number lives in the VERSION file. The practical consequence is a high release cadence: the most recent release listed is 4.26.262 from 2026-09-25, and the repository's last push was on 2026-09-25, so this is a project whose published versions track commits rather than curated milestones. The jump from 4.23.9.0 in 2023 to 4.25.9.0 in 2025 shows the series numbering changing between those points, which is worth noting if you pin versions in packaging. The repository carries packaging/ and a rh_build.sh script, so RPM-oriented packaging has some support, but the README does not document distribution packages; whether your distribution ships inotify-tools is a question for that distribution. The licence is GPL-2.0. If you link against libinotifytools rather than invoke the binaries, the GPL terms apply to that linking, and the repository ships COPYING for the exact text. That is a real consideration for a proprietary product embedding the library, and it is not a decision to make from a summary; read COPYING and, where the stakes are high, take advice.

What a Rust rewrite does and does not change for you

The primary language is now Rust, and the build goes through cargo, but the installed interface is deliberately old. The headers are still C headers, the SONAME is still libinotifytools.so.0, and the Makefile still installs with the historical autotools layout, with prefix defaulting to /usr/local and the usual bindir, libdir, includedir, mandir and docdir variables. Cargo.toml explains why the package metadata is repeated per workspace member instead of using workspace inheritance: to keep Rust 1.63 working. The release profile sets panic = "abort", lto = true and codegen-units = 1, and the dev profile also sets panic = "abort". For an existing consumer of the C library, the interesting claim is the ABI compatibility, since it means a rebuild should not be forced by the language change. For a new user, the rewrite is mostly invisible: you still get two command-line programs and a C API, and the reason to care is that the toolchain requirement is now Rust 1.63 or newer alongside make and a C compiler.

Editorial conclusion

Adopt inotify-tools when a shell script, a build step or a small daemon needs to react to file changes on one Linux box, and when the historical C ABI matters to something you already link against. Do not adopt it as a recursive filesystem crawler, as a cross-platform watcher, or as a replacement for an event pipeline that must survive a burst of thousands of writes per second; the tools expose one inotify instance's semantics and nothing above them. Before committing, check that your kernel and distribution ship a recent enough package, confirm whether you need the static x86_64 or aarch64 builds, and read the man pages for the exact event names your script will match.

Frequently asked questions

What is inotify-tools used for?

It lets inotify's filesystem notification features be used from shell scripts. It ships inotifywait and fsnotifywait for waiting on or monitoring events, inotifywatch and fsnotifywatch for gathering usage statistics, and libinotifytools, a small library with a C API used by the tools and by other programs.

How to install inotify-tools?

The README documents a source build with GNU make driving cargo: run make, then make check, then make install, which defaults to prefix=/usr/local. Requirements are Rust with cargo and rustc 1.63 or newer, GNU make, a C compiler, and a C++ compiler for make check. The README does not document distribution packages.

What is the difference between inotifywait and inotifywatch?

inotifywait waits for or monitors filesystem events, so it is the streaming tool you read line by line. inotifywatch gathers filesystem usage statistics, so it is the counting tool you run over a period to see totals. Both are described in the man pages, which the README names as the source for details.

What are the differences between fanotify and inotify?

inotify-tools is built on inotify, which attaches watches to specific paths and reports events for them. fanotify is a separate Linux interface that operates at filesystem or mount level and can gate access, which is why it suits security tooling; the repository does not document fanotify support.

Is inotify-tools safe to use?

The repository does not make a safety claim, and the README does not discuss security posture. What can be checked from the repository is that releases are cut from commits on master that pass all CI builds, and that the licence is GPL-2.0 with COPYING included.

Official sources

  1. inotify-tools/inotify-tools on GitHub
  2. Issues
  3. License: GPL-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/inotify-tools-inotify-tools.svg)](https://hysenlabs.com/projects/inotify-tools-inotify-tools)