inotify & incrontab | Trigger commands/scripts on directory change


Okay so the other day I came across a problem and a simple solution to that problem. A Christmas miracle so to speak.

Problem

I have a serice called Sonarr which downloads some TV shows every week and moves it to /home/alpha/TVI have another service called Plex which streams these shows to every device I own.Sonarr sets different file permissions for those TV files and Plex can only access those files with certain permissions. If there is anything we should learn in this world is how the linux permissions work.

Up until now I was managing these permissions manually every week, which means manually going into the TV directory and setting up proper permissions on all files. Now this all sounds very good if you have 10 files. But when this number reaches 7000, managing everything manually becomes tedious.


Solution

Now inotify is a linux kernel feature which detects 'changes' in the specified directory. incrontab is another cron like service which uses inotify to detect changes in file system and execute commands. crontab is a "time" based service whereas incrontab is a "change" based serice.

Basically you can achieve automated command execution upon a directory change. incrontab is fairly simple to use.


Install on you distro

For Ubuntu 18 server

sudo apt update -y && apt upgrade -y
sudo apt install inotify-tools incron -y

incron user configuration

incron can only run by users which are defined in /etc/incron.allow, a very clever solution by developers.
All we have to do is put the username in this file who will be allowed to run incrontab.

Check if the service is running

sudo systemctl status incron

incron.service - file system events scheduler
   Loaded: loaded (/lib/systemd/system/incron.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2019-12-25 17:47:01 UTC; 57min ago
  Process: 28218 ExecStart=/usr/sbin/incrond (code=exited, status=0/SUCCESS)
 Main PID: 28225 (incrond)
    Tasks: 1 (limit: 1816)
   CGroup: /system.slice/incron.service
           └─28225 /usr/sbin/incrond

(if service is disabled)

sudo systemctl start incron 

incron define directories and commands

We can create incrons simply by using this command

incrontab -e

The general line format is the following:

<path>      <mask>      <command>


An Example Cron

/home/alpha/hdd1    IN_MODIFY,IN_MOVED_TO     chown -R root:plex /home/alpha/hdd1/tv/*

Breakdown

Syntax Variable Description
path /home/alpha/hdd1 The directory being watched for changes
mask IN_MODIFY Mask that says monitor the directory for any file modifications
mask IN_MOVED_TO Mask that says monitor if any file is moved into the watched directory
command chown -R root:plex /home/alpha/hdd1/tv/* Are the commands that will be executed if any of the masks returns true

If any new file is moved into the TV folder, then incron will run the above command and set permissions on all files. There are some other masks which are defined in the man page of incrond -

 
 IN_OPEN:          File was opened 
 IN_ACCESS:        File was accessed (read) 
 IN_ATTRIB:        Metadata changed (permissions, timestamps, extended attributes, etc.)
 IN_CREATE:        File/directory created in watched directory 
 IN_DELETE:        File/directory deleted from watched directory 
 IN_MODIFY:        File was modified 
 IN_MOVED_TO:      File moved into watched directory 
 IN_MOVE_SELF:     Watched file/directory was itself moved
 IN_MOVED_FROM:    File moved out of watched directory 
 IN_DELETE_SELF:   Watched file/directory was itself deleted
 IN_CLOSE_WRITE:   File opened for writing was closed 
 IN_CLOSE_NOWRITE: File not opened for writing was closed 

Note: incron does not support recursive monitoring

There are a few options out there for this type of thing:

  • crond (limited to every minute)
  • incrond (cannot recursively watch a directory)
  • inotify (what we’re using along with incrond!)
  • PyInotify (python package that does what inotify does).