Take the 2-minute tour ×

I've been Googling and Overflowing for a bit and couldn't find anything usable.

I need a script that monitors a public folder and triggers on new file creation and then moves the files to a private location.

I have a samba shared folder /exam/ple/ on unix mapped to X:\ on windows. On certain actions, txt files are written to the share. I want to kidnap any txt file that appears in the folder and place it into a private folder /pri/vate on unix. After that file is moved, I want to trigger a separate perl script.

EDIT Still waiting to see a shell script if anyone has any ideas... something that will monitor for new files and then run something like:

mv -f /exam/ple/*.txt /pri/vate
share|improve this question
do you need to do it programmatically or can you make use of existing facilities? this is what cron was made for. –  quack quixote Oct 7 '09 at 20:19
can cron be triggered by new file? –  CheeseConQueso Oct 7 '09 at 20:21
i also don't want cron to run the second script over and over... i only want the second script to run after a new file was successfully transferred into the private folder –  CheeseConQueso Oct 7 '09 at 20:27
add comment

8 Answers

up vote 9 down vote accepted

Check incron. It seems to do exactly what you need.

share|improve this answer
this looks pretty decent... too bad i can't install it :< –  CheeseConQueso Oct 8 '09 at 19:25
A great hello world type example of incron: errr-online.com/2011/02/25/… –  mdaddy Jan 4 '12 at 3:01
Can incron be installed on Windows? –  Helen Craigman Sep 26 '13 at 19:05
add comment

If I understand correctly, you just want something like this?


use strict;
use warnings;

use File::Copy

my $poll_cycle = 5;
my $dest_dir = "/pri/vate";

while (1) {
    sleep $poll_cycle;

    my $dirname = '/exam/ple';

    opendir my $dh, $dirname 
        or die "Can't open directory '$dirname' for reading: $!";

    my @files = readdir $dh;
    closedir $dh;

    if ( grep( !/^[.][.]?$/, @files ) > 0 ) {
        print "Dir is not empty\n";

        foreach my $target (@files) {
            # Move file
            move("$dirname/$target", "$dest_dir/$target");

            # Trigger external Perl script
share|improve this answer
ill test it out.... this runs infinitely im guessing? also, im only looking for text files, but the grep bomb is cool to have –  CheeseConQueso Oct 7 '09 at 20:41
@CheeseConQueso: Yes, it's an infinite while loop, polling at the frequency you specify. I haven't rigorously tested the code, but the idea is simple enough. –  ire_and_curses Oct 7 '09 at 20:45
@CheeseConQueso: You can obviously modify the grep to ignore files with a particular suffix if that is your situation. –  ire_and_curses Oct 7 '09 at 20:46
how can i kill the process so its not spinning its wheels in the middle of the night? I want it to run from 7am - 10pm and then hide in the corner for the night –  CheeseConQueso Oct 7 '09 at 20:46
@CheeseConQueso: If you want time-specific functionality, then the simplest answer is probably to remove the while loop and sleep and set the script to run via cron. You can specify the interval to run and also constrain the times. As quack said, this is what cron was designed for. –  ire_and_curses Oct 7 '09 at 20:49
show 4 more comments

File::ChangeNotify allows you to monitor files and directories for changes.


share|improve this answer
add comment
$ python autocmd.py /exam/ple .txt,.html /pri/vate some_script.pl



#!/usr/bin/env python

Adopted from autocompile.py [1] example.

[1] http://git.dbzteam.org/pyinotify/tree/examples/autocompile.py


Linux, Python, pyinotify
import os, shutil, subprocess, sys

import pyinotify
from pyinotify import log

class Handler(pyinotify.ProcessEvent):
    def my_init(self, **kwargs):

    def process_IN_CLOSE_WRITE(self, event):
        # file was closed, ready to move it
        if event.dir or os.path.splitext(event.name)[1] not in self.extensions:
           # directory or file with uninteresting extension
           return # do nothing

            log.debug('==> moving %s' % event.name)
            shutil.move(event.pathname, os.path.join(self.destdir, event.name))
            cmd = self.cmd + [event.name]
            log.debug("==> calling %s in %s" % (cmd, self.destdir))
            subprocess.call(cmd, cwd=self.destdir)
        except (IOError, OSError, shutil.Error), e:

    def process_default(self, event):

def mainloop(path, handler):
    wm = pyinotify.WatchManager()
    notifier = pyinotify.Notifier(wm, default_proc_fun=handler)
    wm.add_watch(path, pyinotify.ALL_EVENTS, rec=True, auto_add=True)
    log.debug('==> Start monitoring %s (type c^c to exit)' % path)

if __name__ == '__main__':
    if len(sys.argv) < 5:
       print >> sys.stderr, "USAGE: %s dir ext[,ext].. destdir cmd [args].." % (

    path = sys.argv[1] # dir to monitor
    extensions = set(sys.argv[2].split(','))
    destdir = sys.argv[3]
    cmd = sys.argv[4:]

    log.setLevel(10) # verbose

    # Blocks monitoring
    mainloop(path, Handler(path=path, destdir=destdir, cmd=cmd,
share|improve this answer
this looks spicy.... I don't have python, but from what you are saying about the notify being native, i might have to install it and try it out... thanks –  CheeseConQueso Oct 8 '09 at 19:57
CheeseConQueso: if search.cpan.org/~drolsky/File-ChangeNotify-0.07/lib/File/… subclass is available then File::ChangeNotify mentioned by @jsoversion can do the same as pyinotify. Quick CPAN search revealed yet another possible solution search.cpan.org/~mlehmann/Linux-Inotify2-1.21/Inotify2.pm –  J.F. Sebastian Oct 8 '09 at 20:36
thanks... i will check it out –  CheeseConQueso Oct 8 '09 at 20:44
add comment

I'm late to the party, I know, but in the interests of completeness and providing info to future visitors;

# Check a File path for any new files
# And execute another script if any are found

FILENAME="*.txt" # Or can be a proper filename without wildcards
ACTION="executeScript.sh argument1 argument2"
LOCKFILE=`basename $0`.lock

# Make sure we're not running multiple instances of this script
if [ -e /tmp/$LOCKFILE ] ; then 
     exit 0
     touch /tmp/$LOCKFILE

# check the dir for the presence of our file
# if it's there, do something, if not exit

if [ -e $POLLPATH/$FILENAME ] ; then
     exec $ACTION
     rm /tmp/$LOCKFILE
     exit 0

Run it from cron;

*/1 7-22/1 * * * /path/to/poll-script.sh >/dev/null 2>&1

You'd want to use the lockfile in your subsequent script ( $ACTION ), and then clean it up on exit, just so you don't have any stacking processes.

share|improve this answer
add comment

This will result in a fair bit of io - stat() calls and the like. If you want rapid notification without the runtime overhead (but more upfront effort), take a look at FAM/dnotify: link text or link text

share|improve this answer
add comment

I don't use ksh but here's how i do it with sh. I'm sure it's easily adapted to ksh.

trap 'rm .newer' 0
touch .newer
while true; do
  (($(find /exam/ple -maxdepth 1 -newer .newer -type f -name '*.txt' -print \
      -exec mv {} /pri/vate \; | wc -l))) && found-some.pl &
  touch .newer
  sleep 10
share|improve this answer
thanks, ill try to convert the syntax and try it out –  CheeseConQueso Jan 21 '11 at 16:08
add comment
while true
    for file in `ls /exam/ple/*.txt`
    sleep 30
share|improve this answer
here is a way to do a search every 30 seconds in korn shell that i found online.... it is not triggered by a new file, its more of a cron-type process.... i still cant find a korn shell script that runs on the presence of a new file –  CheeseConQueso Oct 8 '09 at 15:02
@Cheese, that's a bit of a clunky example - if there are two files in /exam/ple on a single iteration then the for body will run twice, but both files will be mv'ed first time through. So you'll see errors in the second call of mv. Are those backticks needed? –  martin clayton Oct 11 '09 at 20:53
@Martin - good point... I found it online and didn't test it out, so im not sure if the backticks are needed. I just put it up here because it was a shell approach. It's also clunky in that cron can do this same thing –  CheeseConQueso Oct 12 '09 at 12:55
add comment

Your Answer


