How to Trigger Script Execution on Directory Changes in Linux Using Inotify


3 views

As developers, we often need to perform actions automatically when filesystem changes occur. Linux provides a powerful kernel subsystem called inotify that lets us monitor directory modifications in real-time.

The easiest way to leverage inotify is through the inotify-tools package, which provides two main utilities:

sudo apt-get install inotify-tools  # Debian/Ubuntu
sudo yum install inotify-tools     # RHEL/CentOS

Here's a simple example using inotifywait to watch for file creations:

inotifywait -m /path/to/directory -e create |
while read path action file; do
    echo "The file '$file' appeared in '$path' via '$action'"
    # Your script execution here
    /path/to/your/script.sh "$file"
done

You can monitor multiple event types and filter specific patterns:

inotifywait -m /target/dir -e create -e modify -e moved_to |
while read directory event filename; do
    if [[ "$filename" =~ \.csv$ ]]; then
        echo "Processing new CSV: $filename"
        /scripts/process_csv.sh "$directory/$filename"
    fi
done

For production use, create a systemd service:

[Unit]
Description=Directory watcher service
After=network.target

[Service]
ExecStart=/usr/local/bin/watch_script.sh
Restart=always
User=youruser

[Install]
WantedBy=multi-user.target

Save this as /etc/systemd/system/dirwatcher.service then:

sudo systemctl daemon-reload
sudo systemctl enable dirwatcher
sudo systemctl start dirwatcher

For cron-like syntax, consider incron:

sudo apt-get install incron
sudo systemctl enable incron
sudo systemctl start incron

Then edit the incrontab:

/path/to/watch IN_CREATE,IN_MODIFY /path/to/script.sh $@/$#

Directory monitoring is an essential capability for many automation tasks - from log processing to file synchronization. Linux offers several robust solutions for watching file system changes and triggering actions.

The most efficient method uses Linux's inotify API, which provides file system event monitoring at the kernel level. The basic workflow involves:

# Install inotify-tools if not present
sudo apt-get install inotify-tools  # Debian/Ubuntu
sudo yum install inotify-tools      # RHEL/CentOS

Here's a simple script that watches for new files in a directory and executes a command:

#!/bin/bash
DIR_TO_WATCH="/path/to/directory"
COMMAND_TO_RUN="./process_file.sh"

inotifywait -m -r -e create,move --format '%w%f' "$DIR_TO_WATCH" |
while read FILE
do
    # Execute your command here
    $COMMAND_TO_RUN "$FILE"
done

For more robust solutions, systemd's path units provide excellent functionality:

# /etc/systemd/system/dir-watcher.path
[Unit]
Description=Watch /data directory for changes

[Path]
PathModified=/data/
Unit=dir-watcher.service

[Install]
WantedBy=multi-user.target

# /etc/systemd/system/dir-watcher.service
[Unit]
Description=Process directory changes

[Service]
Type=oneshot
ExecStart=/usr/local/bin/process_files.sh
User=www-data

Other methods worth considering:

  • incron: Cron-like daemon for filesystem events
  • fswatch: Cross-platform file change monitor
  • fanotify: Alternative to inotify with different characteristics

When implementing directory monitoring:

  • Be mindful of recursive watches on large directories
  • Consider event queue limits (check /proc/sys/fs/inotify/max_queued_events)
  • Implement proper error handling for edge cases

For more complex scenarios, here's a Python solution using pyinotify:

import pyinotify
import subprocess

class EventHandler(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event):
        subprocess.run(['/path/to/script', event.pathname])

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

wdd = wm.add_watch('/target/directory', pyinotify.IN_CREATE)
notifier.loop()