How to register a callback to execute on a file change in Linux?

by keegan.towne , in category: General Help , 7 months ago

How to register a callback to execute on a file change in Linux?

Facebook Twitter LinkedIn Telegram Whatsapp

2 answers

Member

by brock , 7 months ago

@keegan.towne 

To register a callback to execute on a file change in Linux, you can use the inotify API, which is a Linux kernel subsystem for monitoring file system events. Here's an example of how you can do it using inotify in C programming language:

  1. Include the necessary headers:
1
2
3
4
5
6
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>


  1. Set up the inotify instance and add the file/directory to be monitored:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
int fd = inotify_init();
if (fd == -1) {
    perror("inotify_init");
    exit(EXIT_FAILURE);
}

int wd = inotify_add_watch(fd, "/path/to/file", IN_MODIFY);
if (wd == -1) {
    perror("inotify_add_watch");
    exit(EXIT_FAILURE);
}


Replace /path/to/file with the actual path of the file or directory you want to monitor. IN_MODIFY is the event mask that specifies the type of events to be monitored (in this case, file modifications).

  1. Set up the event loop to receive and process events:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
char buffer[4096];
ssize_t bytesRead;

while (1) {
    bytesRead = read(fd, buffer, sizeof(buffer));
    if (bytesRead == -1) {
        perror("read");
        exit(EXIT_FAILURE);
    }

    // Process the events
    struct inotify_event *event;
    for (char *ptr = buffer; ptr < buffer + bytesRead; ptr += sizeof(struct inotify_event) + event->len) {
        event = (struct inotify_event *)ptr;
        
        if (event->mask & IN_MODIFY) {
            printf("File modified: %s
", event->name);
    
            // Callback function logic goes here
            
        }
    }
}


The above code reads the events from the inotify file descriptor (fd) and processes them in a loop. In this example, it prints the name of the modified file. Replace the print statement and add your own callback function logic as needed.

  1. Clean up resources:
1
2
inotify_rm_watch(fd, wd);
close(fd);


After you're done monitoring the file changes, don't forget to remove the watch using inotify_rm_watch and close the inotify descriptor with close(fd).


Note: This is just a basic example of using inotify to register a callback on file changes. You can find more information about the inotify API and its capabilities in the Linux man pages (man 7 inotify).

by wayne.swaniawski , a month ago

@keegan.towne 

If you prefer to use a higher-level programming language such as Python, you can achieve the same functionality using the pyinotify library. Here's an example in Python:


First, you need to install the pyinotify library if you haven't already:

1
pip install pyinotify


Then you can use the following Python script to monitor file changes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import pyinotify

class EventHandler(pyinotify.ProcessEvent):
    def process_IN_MODIFY(self, event):
        print("File modified:", event.pathname)
        # Callback function logic goes here

wm = pyinotify.WatchManager()
handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler)

wdd = wm.add_watch('/path/to/file', pyinotify.IN_MODIFY)

notifier.loop()


Replace /path/to/file with the actual path of the file you want to monitor. In the process_IN_MODIFY method, you can add your callback function logic.


When the file is modified, the process_IN_MODIFY method will be called, and you can perform your desired actions inside this method.


Don't forget to stop the monitoring and release resources properly when you're done:

1
notifier.stop()


This Python example achieves the same goal as the C program using inotify, but with a higher-level and more Pythonic approach. You can explore the pyinotify library documentation for more advanced usage and options.