Monitoring a Directory on Linux¶
Practical approaches for watching directory changes from a Linux system or service.
This English edition keeps the original illustrations and reproducible command or configuration examples.


Commands and configuration¶
bash复制代码# Debian/Ubuntu
sudo apt-get install inotify-tools
# CentOS/RHEL
sudo yum install inotify-tools
#!/bin/bash
# Function to display usage
usage() {
echo "Usage: $0 <source_directory> <destination_directory> [--verbose]"
exit 1
}
# Check if the correct number of arguments is passed
if [ $# -lt 2 ]; then
usage
fi
# Get the arguments
SOURCE_DIR="$1"
DEST_DIR="$2"
VERBOSE=false
if [ "$3" == "--verbose" ]; then
VERBOSE=true
fi
# Check if the source and destination directories exist
if [ ! -d "$SOURCE_DIR" ]; then
echo "Error: Source directory $SOURCE_DIR does not exist."
exit 1
fi
if [ ! -d "$DEST_DIR" ]; then
echo "Error: Destination directory $DEST_DIR does not exist."
exit 1
fi
# Function to print verbose messages
verbose_echo() {
if $VERBOSE; then
echo "$1"
fi
}
# Check if inotify-tools is installed
if ! command -v inotifywait &> /dev/null; then
echo "Warning: inotify-tools is not installed. Falling back to polling."
FALLBACK=true
else
FALLBACK=false
fi
# Sync logic for inotify
inotify_sync() {
verbose_echo "Using inotify for directory monitoring..."
inotifywait -m -r -e create,modify,delete "$SOURCE_DIR" --format '%w%f %e' | while read FILE EVENT; do
RELATIVE_PATH="${FILE#$SOURCE_DIR/}"
DEST_PATH="$DEST_DIR/$RELATIVE_PATH"
case $EVENT in
CREATE,ISDIR)
verbose_echo "Directory created: $FILE"
mkdir -p "$DEST_PATH"
;;
CREATE|MODIFY)
verbose_echo "File created or modified: $FILE"
mkdir -p "$(dirname "$DEST_PATH")"
cp "$FILE" "$DEST_PATH"
;;
DELETE|DELETE,ISDIR)
verbose_echo "File or directory deleted: $FILE"
rm -rf "$DEST_PATH"
;;
esac
done
}
# Sync logic for fallback (polling)
polling_sync() {
verbose_echo "Using polling method for directory monitoring..."
TEMP_FILE="/tmp/prev_files.txt"
# Initially record the current list of files and directories
find "$SOURCE_DIR" -type f | sort > "$TEMP_FILE"
while true; do
CURRENT_FILES=$(find "$SOURCE_DIR" -type f | sort)
if ! diff <(echo "$CURRENT_FILES") "$TEMP_FILE" > /dev/null; then
verbose_echo "Changes detected, syncing..."
rsync -av --delete "$SOURCE_DIR/" "$DEST_DIR/"
echo "$CURRENT_FILES" > "$TEMP_FILE"
fi
sleep 0.5
done
}
# Use appropriate method based on tool availability
if $FALLBACK; then
polling_sync
else
inotify_sync
fi
Practical notes¶
Test each change on a recoverable target, keep logs from the boot or failure path, and record the exact kernel and userspace versions used in the result.