What is the proper way to use inotify?
- Documentation ( from Monitor file system activity with
inotify )
The inotify
C API
inotify
provides three system calls to build file system monitors of all kinds:
inotify_init()
creates an instance of theinotify
subsystem in the kernel and returns a file descriptor on success and-1
on failure. Like other system calls, ifinotify_init()
fails, checkerrno
for diagnostics.inotify_add_watch()
, as its name implies, adds a watch. Each watch must provide a pathname and a list of pertinent events, where each event is specified by a constant, such asIN_MODIFY
. To monitor more than one event, simply use the logical or — the pipe (|) operator in C—between each event. Ifinotify_add_watch()
succeeds, the call returns a unique identifier for the registered watch; otherwise, it returns-1
. Use the identifier to alter or remove the associated watch.inotify_rm_watch()
removes a watch.
The read()
and close()
system calls are also needed. Given the descriptor yielded by inotify_init()
, call read()
to wait for alerts. Assuming a typical file descriptor, the application blocks pending the receipt of events, which are expressed as data in the stream. The common close() on the file descriptor yielded from inotify_init()
deletes and frees all active watches as well as all memory associated with the inotify instance. (The typical reference count caveat applies here, too. All file descriptors associated with an instance must be closed before the memory consumed by the watches and by inotify is freed.)
- An example ( from Kernel Korner - Intro to inotify )
#include "inotify.h"
#include "inotify-syscalls.h"
int wd;
wd = inotify_add_watch (fd,
"/home/rlove/Desktop", IN_MODIFY | IN_CREATE | IN_DELETE);
if (wd < 0)
perror ("inotify_add_watch");
This example adds a watch on the directory /home/rlove/Desktop for any modifications, file creations or file deletions.
How to use inotifywait to wait till a file is created and is written content with timeout
You cannot wait for ./hello.txt
because it doesn't exist yet, so the kernel has no node to attach the inotify object to.
You need to wait on the parent directory (.
).
The problem is that you have to find a way to filter out only the specific file.
If you have at least version 3.20.1 of inotifywait
, you can just use the option --include
to pass a regex with the name of your file.
If you don't, ...well, you can try to use the option --exclude
and write a reversed regex or you can write a script to filter the result externaly. Both of these options are rather inconvenient.
Answers to this question describe various ways of making the filter: https://unix.stackexchange.com/q/323901/133542.
If you have the new version, the command will look like this:
inotifywait -e close_write -t 30 --include 'hello\.txt' .
A few remarks:
- Flags
-m
and-t
are not allowed together (at least in my version). However, you're waiting for a single specific event so there is no need for-m
. - In your code, you're waiting for the event
create
but you've stated that you want to know when the file is written. I've changed the event toclose_write
which means that the file is being closed after being opened in writable mode. - The flag
--fromfile
means that the file contains a list of files to be watched, not that it is being watched itself. I've removed the flag. - The flag
-r
is necessary only if you want to watch an entire tree of directories. If the file is directly in the watched directory, you don't need it.
How to use inotify in C?
The 0x8000
corresponds to IN_IGNORED
. Its presence in the mask indicates that the inotify
watch had been removed because the file had been removed. Your editor probably removed the old file and put a new file in its place. Changing the file a second time had no effect because the watch had been removed.
The name is not being returned because you are not watching a directory.
From the inotify
man page.
The
name
field is only present when an event is returned for a file inside a watched directory; it identifies the file pathname relative to the watched directory....
IN_IGNORED -- Watch was removed explicitly (inotify_rm_watch(2)) or automatically (file was deleted, or file system was unmounted).
How to continuously monitor the directory using dnotify /inotify command
Inotify itself is a kernel module accesible via calls from e.g. a C program.
https://linux.die.net/man/7/inotify
There is an application suite called inotify-tools, which contains:
inotifywait - wait for changes to files using inotify
http://linux.die.net/man/1/inotifywait
and
inotifywatch - gather filesystem access statistics using inotify
http://linux.die.net/man/1/inotifywatch
You can use inotify directly from command line, e.g. like this to continuously monitor for all changes under home directory (may generate lots of output):
inotifywait -r -m $HOME
And here is a script that monitors continuously and reacts to Apache log activity, copied from the man file of inotifywait:
#!/bin/sh
while inotifywait -e modify /var/log/messages; do
if tail -n1 /var/log/messages | grep httpd; then
kdialog --msgbox "Apache needs love!"
fi
done
Related Topics
How Pthread_Mutex_Lock Is Implemented
How to Automatically Add User Account and Password with a Bash Script
How to Convert \Uxxxx Unicode to Utf-8 Using Console Tools in *Nix
Best Way to Get MAChine Id on Linux
How to Calculate CPU Utilization of a Process & All Its Child Processes in Linux
Bash: Integer Expression Expected
In Bash, How to Add a String After Each Line in a File
How to Configure Linux Capabilities Per User
What Is an Anonymous Inode in Linux
How to Pass a Wildcard Parameter to a Bash File
Docker Command Can't Connect to Docker Daemon
Is /Usr/Local/Lib Searched for Shared Libraries
What Is Path on a MAC (Unix) System
How to Pass Parameters to a Bash Script