Keywords: macOS | file monitoring | fswatch | launchd | FSEvents
Abstract: This article provides an in-depth exploration of solutions for monitoring folder changes and automatically executing scripts on macOS. It focuses on the fswatch tool based on the FSEvents API, covering installation methods, basic syntax, advanced options, and practical examples. Additionally, it briefly compares launchd as a system-level monitoring alternative, helping developers choose the appropriate tool based on their needs.
Introduction
In macOS development environments, there is often a need to monitor specific folders for changes and automatically execute corresponding actions when files are created, modified, or deleted. While Linux systems have mature tools like inotifywait, macOS requires different technical approaches. This article details two mainstream methods: the fswatch tool based on the FSEvents API and the system service launchd.
fswatch: The Core Tool for macOS File System Monitoring
fswatch is a cross-platform file system monitoring tool that leverages the FSEvents API on macOS for efficient monitoring. FSEvents is a macOS-specific file system event notification framework that offers lower overhead and higher real-time performance compared to polling methods.
Installation Methods
It is recommended to use Homebrew for installation:
brew update
brew install fswatch
For manual compilation and installation, execute the following commands:
cd /tmp
git clone https://github.com/alandipert/fswatch
cd fswatch/
make
cp fswatch /usr/local/bin/fswatch
Manual installation requires Xcode command line tools to provide C compiler support.
Basic Usage Patterns
For fswatch version 1.x and above, the recommended pattern uses pipes combined with xargs:
fswatch -o ~/watch_path | xargs -n1 -I{} ~/script_path/change.sh
The -o option causes fswatch to output the number of events rather than detailed event information, which is then passed to the processing script via xargs. -I{} specifies the replacement string to prevent the event count from being appended to the end of the command.
The syntax for earlier version 0.x is simpler:
fswatch ~/watch_path ~/script_path/change.sh
Advanced Configuration Options
fswatch offers a rich set of configuration options:
-r, --recursive: Monitor subdirectories recursively-l, --latency=DOUBLE: Set event latency in seconds-e, --exclude=REGEX: Exclude paths matching the regular expression-1, --one-event: Exit after receiving the first batch of events-t, --timestamp: Output event timestamps-x, --event-flags: Output detailed event flags
Complete options can be viewed via fswatch --help.
Practical Application Example
The following script demonstrates monitoring the ~/Documents/processed directory and automatically processing new files:
#!/bin/bash
# process_new_files.sh
WATCH_DIR="~/Documents/processed"
SCRIPT_DIR="$(dirname "$0")"
fswatch -o "$WATCH_DIR" | while read num_events
do
# Get the latest file
latest_file=$(ls -t "$WATCH_DIR" | head -1)
if [ -n "$latest_file" ]; then
echo "Processing new file: $latest_file"
# Execute actual processing logic
"$SCRIPT_DIR/process_file.sh" "$WATCH_DIR/$latest_file"
fi
done
launchd: System-Level Monitoring Solution
As macOS's system service management framework, launchd provides an alternative file monitoring approach. Through XML configuration files, monitoring rules can be defined, making it suitable for scenarios requiring system-level persistent monitoring.
Basic Configuration Example
Create ~/Library/LaunchAgents/com.example.monitor.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.monitor</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/logger</string>
<string>Path modified</string>
</array>
<key>WatchPaths</key>
<array>
<string>/Users/username/Desktop/</string>
</array>
</dict>
</plist>
Service Management
Load the monitoring service:
launchctl load ~/Library/LaunchAgents/com.example.monitor.plist
Unload the service:
launchctl unload ~/Library/LaunchAgents/com.example.monitor.plist
Technical Comparison and Selection Recommendations
Advantages of fswatch:
- High real-time performance, event-driven
- Flexible configuration with rich filtering options
- Cross-platform compatibility (macOS, Linux, BSD)
- Suitable for development debugging and temporary monitoring tasks
Advantages of launchd:
- System-level integration, auto-start on boot
- Better resource management, scheduled by the system
- Suitable for production environment persistent monitoring
- Deep integration with macOS system
Selection recommendation: fswatch is recommended for development environments, while launchd can be considered for production environments or scenarios requiring system services.
Performance Optimization Suggestions
- Set Appropriate Latency: Use the
-lparameter to adjust event collection latency, balancing real-time performance and system load - Path Filtering: Exclude irrelevant directories via
-eto reduce event volume - Avoid Deep Recursion: Avoid using
-runnecessarily, or limit monitoring directory depth - Batch Processing: Combine
-oandxargsfor batch event processing to reduce script invocation overhead
Common Issues and Solutions
Issue 1: fswatch produces no output or responds with delay
Solution: Check path permissions, use the -v parameter to enable verbose output for debugging. Ensure the monitored path exists and is accessible.
Issue 2: Script execution permission problems
Solution: Ensure the processing script has execution permissions (chmod +x script.sh) and specify the interpreter at the script's beginning (#!/bin/bash).
Issue 3: launchd service fails to start
Solution: Check plist file syntax using plutil -lint file.plist for validation. Ensure WatchPaths paths are correct.
Conclusion
File system monitoring on macOS can be achieved through two solutions: fswatch and launchd. fswatch, with its flexibility and real-time performance, is the preferred choice for development, while launchd is more suitable for system-level monitoring needs. Understanding the principles and applicable scenarios of both tools enables developers to build efficient and reliable file monitoring systems.