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).