On GNU/Linux exists a library called inotify which does that, notifies for changes(change, create, delete) of files into a directory. Over Mac there is FSEvents, which essentially do the same as inotify, with some exceptions of course.

Now, what happened if I have 2 servers which I want to monitor for file changes?. You could say: «write one app and run on 2 servers». Yeah!, nice answer, but 1 of them is running GNU/Linux and the other one is running MacOS, so we need something like Ruby to do so.

First we install fssm(File System State Monitor) from rubygems:

gem install fssm

Maybe you need do the above as root. Next go to your favorite editor, I use Geany.

Of course, the first lines will be:

#!/usr/bin/env ruby

require 'rubygems'
require 'fssm'

The first line calls for the ruby interpreter and the next 2 loads rubygems and fssm ruby extensions.

Now go to the magic code, it’s pretty simple and easy to undestand.

FSSM.monitor("/tmp/test") do
	update do |b, r|
		puts "Someone changes the file '#{r}' into '#{b}'"

	create do |b, r|
		puts "Someone creates the file '#{r}' into '#{b}'"

	delete do |b, r|
		puts "Someone deletes the file '#{r}' into '#{b}'"

The first line enters to a loop that watch for filesystem changes only into /tmp/test directory.

The second line states which actions gonna take the program if the some file inside the /tmp/test directory has been updated and passes the variables b and r to the block(in this case just line number 3). r is the relative path to the updated, b is the absolute path(/tmp/test in this case); then a message is printed on the screen.

The code for the created and deleted files are the same.

Now, the FSSM.monitor has 3 possible arguments, we just use 1 of them in the above example.

The second parameter is a glob pattern(or array of glob patterns) that the files must match to be watched by fssm, if this parameter is not specified, the default is **/*.

The third parameter is for watching directories. By default, fssm watch just for file changes, if we want to watch directories too we need to pass the option here, doing this :directories => true, and additionally, the blocks for update, delete and create must have another block variable:

delete do |b, r, t|
	puts "Someone delete #{r} into #{b} which is a #{t == :directory ? 'directory' : 'file'}"

Where t is the type, it means if is a directory or a file, we check for this in a «short» if statement. t variable can be the symbols :directory or :file. AFAIK this will not work as expected on MacOS, I appreciate if someone can confirm, I’m a poor guy and I don’t own a Mac.😛. Anyway it don’t watch for created, deleted or updated directories, but if you create a directory inside /tmp/test and then create a file inside, it will be detected.

So, the complete code with checking for directories is:

#!/usr/bin/env ruby

require 'rubygems'
require 'fssm'

FSSM.monitor("/tmp/test", '**/*', :directories => true) do
 update do |b, r, t|
 puts "Someone changes #{r} into #{b} which is a #{t == :directory ? 'directory' : 'file'}"

 create do |b, r, t|
 puts "Someone create #{r} into #{b} which is a #{t == :directory ? 'directory' : 'file'}"

 delete do |b, r, t|
 puts "Someone delete #{r} into #{b} which is a #{t == :directory ? 'directory' : 'file'}"

That’s it!. Now we can watch for filesystem changes in many different systems. It’s so nice and useful. Of course we need to develop and work a little more to do something nicer.

I hope this will help someone, works for me.

See you soon.

2 responses »

  1. a says:

    Qué jódido está tu inglés, hasta pena ajena me dió…

  2. Ivan says:

    Si, ¡qué barbaridad!, por eso trato de practicarlo acá. Tal vez podamos hacer trueque, tú me enseñas inglés y yo te enseño español. Primera clase:

    «¡Qué jodido está tu inglés!, hasta pena ajena me dio».

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s