9

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:

#!/bin/ksh
mv -f /exam/ple/*.txt /pri/vate
3
  • 1
    do you need to do it programmatically or can you make use of existing facilities? this is what cron was made for. Commented Oct 7, 2009 at 20:19
  • can cron be triggered by new file? Commented Oct 7, 2009 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 Commented Oct 7, 2009 at 20:27

8 Answers 8

9

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

Sign up to request clarification or add additional context in comments.

3 Comments

this looks pretty decent... too bad i can't install it :<
A great hello world type example of incron: errr-online.com/2011/02/25/…
Can incron be installed on Windows?
6

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

#!/usr/bin/perl

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
            system('./my_script.pl');
    }
}

9 Comments

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: 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.
@CheeseConQueso: You can obviously modify the grep to ignore files with a particular suffix if that is your situation.
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: 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.
|
5

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

https://metacpan.org/pod/File::ChangeNotify

Comments

3

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

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

POLLPATH="/path/to/files"
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
else
     touch /tmp/$LOCKFILE
fi

# 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
else
     rm /tmp/$LOCKFILE
     exit 0
fi

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.

Comments

2
$ python autocmd.py /exam/ple .txt,.html /pri/vate some_script.pl

Advantages:

autocmd.py:

#!/usr/bin/env python
"""autocmd.py 

Adopted from autocompile.py [1] example.

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

Dependencies:

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

import pyinotify
from pyinotify import log

class Handler(pyinotify.ProcessEvent):
    def my_init(self, **kwargs):
        self.__dict__.update(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

        try:
            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:
            log.error(e)

    def process_default(self, event):
        pass


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)
    notifier.loop()


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

    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,
                           extensions=extensions))

2 Comments

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: 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
1

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

Comments

1

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

#!/bin/sh
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
done

Comments

0
#!/bin/ksh
while true
do
    for file in `ls /exam/ple/*.txt`
    do
          # mv -f /exam/ple/*.txt /pri/vate
          # changed to
          mv -f  $file  /pri/vate

    done
    sleep 30
done

3 Comments

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
@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 - 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.