Baeldung Pro – Linux – NPI EA (cat = Baeldung on Linux)
announcement - icon

Learn through the super-clean Baeldung Pro experience:

>> Membership and Baeldung Pro.

No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.

1. Overview

The Linux operating system supports powerful tools we can use to monitor directories for changes. For instance, it supports the dnotify and inotify commands which we can utilize to perform this crucial task.

In this tutorial, we’ll take a look at using both the dnotify and inotify tools when continuously monitoring a directory.

2. Monitoring Directories

To begin with, monitoring this directory entails keeping track of changes in the directory:

  • creation, deletion, or modification of files
  • changes in permission or ownership
  • access or moving of files

Monitoring a directory continuously can be helpful in system administration for operations such as logging changes in a critical path and triggering actions when files are added or removed, to mention a couple.

Other examples include monitoring sensitive directories for unauthorized changes. For instance, we can monitor the /etc/ directory for configuration files.

3. Example Subset

Next, we check a sample directory for demonstration purposes:

$ tree test_directory
test_directory
├── test_file1.txt
└── test_subdirectory

1 directory, 1 file

Above, the tree command enables us to see that test_directory contains the file test_file1.txt and the subdirectory test_subdirectory.

So, let’s explore a toolset we can use for the purpose.

4. dnotify and inotify

dnotify and inotify are Linux kernel-level tools that provide monitoring capabilities for files and directories. Both are accessible through system calls.

4.1. dnotify

dnotify, introduced in Linux kernel 2.4, uses file descriptors for monitoring directories. However, it has since been deprecated due to its limitations:

  • cannot monitor individual files directly, only directories
  • requires each monitored directory to have an open file descriptor, which can lead to the exhaustion of resources if too many directories are monitored
  • less efficient and complicated to use compared to inotify

Instead, most systems use inotify.

4.2. inotify

On the other hand, inotify is more advanced and was introduced in the Linux kernel 2.6.13. It’s often more suitable to use when compared to dnotify:

  • provides support for individual files and entire directories
  • can monitor efficiently with fewer resources which makes it suitable for large-scale monitoring
  • provides detailed event notifications since it can distinguish between different types of events, for instance, file creation vs. file modification
  • more widely supported in modern Linux distributions unlike the deprecated dnotify

Therefore, inotify is more fit to use compared to dnotify for monitoring.

5. Monitoring the Directory Using inotify

Specifically, we can access inotify using command-line tools such as inotifywait and inotifywatch from the inotify-tools package.

5.1. Installation

Before we can get started with inotify, we should ensure that the inotify-tools package is installed on the system.

For Ubuntu and other Debian-based Linux distributions, we can install it via APT:

$ sudo apt install inotify-tools

In particular, this package provides two key utilities:

  • inotifywait waits for filesystem events and prints them to the terminal
  • inotifywatch collects as well as monitors statistics about filesystem events

In our case, let’s use inotifywait to monitor the directory test_directory continuously.

5.2. Creating a Script to Monitor the Directory

Here, we create the Bash script monitor_directory.sh:

$ cat monitor_directory.sh
#!/bin/bash

# Directory to monitor
MONITORED_DIR="$1"

# Start monitoring
echo "Monitoring directory: $MONITORED_DIR"

inotifywait -m -r \
    -e create -e modify -e delete -e move \
    --format '%T %w %f %e' \
    --timefmt '%Y-%m-%d %H:%M:%S' \
    "$MONITORED_DIR" | while read DATE TIME DIR FILE EVENT
    do
        echo "[$DATE $TIME] Event detected: $EVENT on $DIR$FILE"
    done

The script specifies the path to the directory we want to monitor, taking it from the first command-line argument. After that, it ensures that the proper tooling is installed.

Once the script ensures inotifywait exists on the system, it initiates the monitoring:

  • -m enables continuous monitoring
  • -r ensures the monitoring is recursive
  • -e specifies events such as create, modify, delete, and move
  • –format option customizes the format of the output
  • –timefmt formats the timestamp
  • while read loop processes each detected event

This script prints a message whenever it detects a change.

Let’s see what happens when we execute the Bash script:

$ bash monitor_directory.sh /home/maurice/Desktop/test_directory
Monitoring directory: /home/maurice/Desktop/test_directory
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.

So far, the script has not detected any changes. Now, let’s navigate to the test_directory and begin making the changes.

5.3. Triggering the CREATE Event

First, let’s use the touch command to create the file test_file.txt inside test_directory:

$ touch test_file2.txt

Let’s now display what the script prints:

[2025-01-03 07:26:43] Event detected: CREATE on /home/maurice/Desktop/test_directory/test_file2.txt

It captures the CREATE event, meaning a file creation was detected.

5.4. Triggering the MODIFY Event

Let’s use the echo command with redirection to update the content of test_file1.txt:

$ echo "Adding text" >> test_file1.txt

As expected, the monitor output reflects this action:

[2025-01-03 08:02:01] Event detected: MODIFY on /home/maurice/Desktop/test_directory/test_file1.txt

This way, we trigger a MODIFY event by appending text to a file in the directory.

5.5. Triggering the DELETE Event

Let’s delete the test_file2.txt file using the rm command:

$ rm test_file2.txt

Thus, the monitoring output updates again:

[2025-01-03 08:22:07] Event detected: DELETE on /home/maurice/Desktop/test_directory/test_file2.txt

Thus, we triggered a DELETE event by deleting test_file2.txt.

5.6. Triggering the MOVE Event

Here, we use the mv command to move test_file1.txt into the subdirectory test_subdirectory:

$ mv test_file1.txt test_subdirectory/

So, let’s see how the output logs this MOVE event:

[2025-01-03 08:36:43] Event detected: MOVED_FROM on /home/maurice/Desktop/test_directory/test_file1.txt
[2025-01-03 08:36:43] Event detected: MOVED_TO on /home/maurice/Desktop/test_directory/test_subdirectory/test_file1.txt

Well, inotify generates two separate events when we move the file:

  • MOVED_FROM shows that the file was moved from the location /home/maurice/Desktop/test_directory/
  • MOVED_TO shows that the file was moved to the location /home/maurice/Desktop/test_directory/test_subdirectory/

These two events ensure we capture the removal of the file from the source and its addition to the destination. Of course, if the source or destination is outside the monitored path, no notification would be generated for either or both.

6. Improvements and Practical Use

Critically, we can automate file management tasks during directory monitoring. For instance, we may want to automatically move new files added to a directory into a subdirectory for further processing or organization.

For this, let’s modify the Bash script monitor_directory.sh:

$ cat monitor_directory_improved.sh
#!/bin/bash

MONITORED_DIR="$1"
OUTPUT_DIR="$1/test_subdirectory"

mkdir -p "$OUTPUT_DIR"

inotifywait -m -e create "$MONITORED_DIR" | while read DIR EVENT FILE
do
    echo "New file detected: $FILE"
    mv "$MONITORED_DIR/$FILE" "$OUTPUT_DIR"
    echo "File moved to $OUTPUT_DIR"
done

Notably, we only use the -m and -e flags to clean the output and make it easier to process automatically.

After that, let’s add a new file to trigger the CREATE event:

$ touch test_file3.txt

Now, let’s see the output from the monitoring script:

...
Setting up watches.
Watches established.
New file detected: test_file3.txt
File moved to /home/maurice/Desktop/test_directory/test_subdirectory

So, creating the file test_file3.txt triggers a CREATE event and in turn, the script moves the file test_file3.txt to a different location.

Lastly, we can save the output to a file by creating logs for debugging purposes.

7. Conclusion

In this article, we explore how to monitor directories for changes.

Although dnotify provides this functionality, inotify has become the standard because of its efficiency and ease of use. For inotify, we learned that the inotify-tools package provides the utility inotifywait that we can use to easily set up continuous monitoring for any directory in terms of different events. Furthermore, we incorporated scripts for automation.

Now, we can automate workflows, improve security, and enhance system management.

2 Comments
Oldest
Newest
Inline Feedbacks
View all comments