Watching Files for Changes
OS X applications make use of various support files and these files get read and written quite frequently behind the scenes. Especially when troubleshooting some problem, it is often useful to be notified when relevant files get modified. I wrote a Perl script: 'watchfile' that prints a message when one of the specified files gets modified.You specify the files or folders you want it to watch in the usual way - as a space separated list on the command-line. For example, if you want it to watch the file ~/Library/Preferences/com.apple.finder.plist, you would run the command:
% watchfile ~/Library/Preferences/com.apple.finder.plistOr if you wanted to watch all of the com.apple preference files, you would run the command:
% watchfile ~/Library/Preferences/com.apple.*The script will print a message "info stored" when it starts watching each file and then it will check on the file each 10 seconds after that and print a message if anything about the file has changed. The messages are somewhat cryptic, indicating which things have changed since the last check.
Here's a list of the things that might be reported:
- ino
The inode number (numerical id) of the file has changed. This means that the file has been removed and recreated (with the same name). - mode
The file permissions have changed. - nlink
The number of hard links to this file have changed. If it is a folder that is being watched, a change in the number of hard links indicates a change in the number of files in that folder. - uid
The owner of the file has changed. - gid
The group ownership of the file has changed. - size
The size (in bytes) of the file has changed. - md5
The MD5 digest of the file's contents has changed. (See option "-md5" below) - atime
The time of last access of the file has changed. (See option "-atime" below) - mtime
The time of last data modification has changed. This usually means that the contents of the file have been modified. - ctime
The time of last status change has changed. This usually means that the ownership or permissions have changed.
Command-line Options:
- -interval
By default, the script checks on the file(s) every 10 seconds. If you want to specify a different time interval, use the -interval option.
E.g.: watchfile -interval 60 ~/Library/Preferences/com.apple.*.
The longer the time interval, the less CPU will be used. But normally, CPU usage of this script is not a problem. On my iBook 600, watching all the com.apple preference files with the default 10 second interval takes much less than 1% of the CPU. - -atime
By default, the script does not report on access-time changes because changes to the files are more significant. And some files are accessed quite frequently so being notified each time would add to the noise. If you want to be notified of access-time changes, use the -atime option.
E.g.: watchfile -atime ~/Library/Preferences/com.apple.* - -md5
If you want the script to calculate and compare an MD5 digest for each file, use the -md5 option. This is an advanced option and not usually desirable unless you are monitoring a file for security purposes. The use of this option requires the Perl module Digest::MD5 which is not installed by default on OS X. Note that access-time changes will not be reported if the -md5 option is used since the file is accessed in order to compute the MD5 digest. Note also that doing MD5 digests of directories is not supported.
E.g.: watchfile -md5 ~/Library/Preferences/com.apple.* - -rsrc
By default, the script does not report on changes to the resource fork of files. If you want to be notified of changes to the resource fork, use the -rsrc option.
The script should need only small changes to get it to work on other operating systems (anywhere that Perl is installed). It should work as is on any Linux system. After changing the line that does the 'ls -ld', it should even work on Windows if you install Perl.
Alternatives
There are several other programs that watch files for changes.The well-known application Tripwire occupies a different ecological niche. It is explicitly concerned with security and is far more sophisticated, with concomitant complexity of use.
The Radmind application has a different focus - it is usually used for maintaining multiple machines in a known state.
The bubblegum program is quite similar to the 'watchfile' script in intent but is considerably more sophisticated. It is a compiled C program that is designed to run as a daemon.
The 'watchfile' script was intended mostly for impromptu troubleshooting sessions where the ease of modification of a script (as opposed to a compiled executable) is often a big advantage.
Note: this script was first published as a MacOSXHints article.