Automatically execute a program when file is written
Automatically execute a program when file is written
Hello,
I have a program that writes files in the filesystem.
Is there a way to execute a program automatically after file is created in specific folder?
Thanks,
I have a program that writes files in the filesystem.
Is there a way to execute a program automatically after file is created in specific folder?
Thanks,
- WhatsHisName
- Posts: 1549
- Joined: 2005/12/19 20:21:43
- Location: /earth/usa/nj
Automatically execute a program when file is written
I would think the simplest way would be to poll through cron for the presence of the file or for files newer than the previous check and start the program as needed.
If you need faster than 1 min. increments, then you could create a simple daemon to perform a similar task at shorter intervals.
But at times like this, I tend to get out my copies of "Classic Shell Scripting" and "Bash Cookbook" from O'Reilly and start thumbing through the pages. :-)
There may be other perl/python options, too.
If you need faster than 1 min. increments, then you could create a simple daemon to perform a similar task at shorter intervals.
But at times like this, I tend to get out my copies of "Classic Shell Scripting" and "Bash Cookbook" from O'Reilly and start thumbing through the pages. :-)
There may be other perl/python options, too.
Re: Automatically execute a program when file is written
:-)
Thanks for suggestions...
I got those in mind(and they got rejected), but the issue is much more complex...
It is even preferred not to have the file written to the disk since it contains sensitive information.
Maybe some sort of FUSE filesystem...
The solution for now is cron job + encrypted filesystem, but I wanted to see if anyone found something else.
Thanks for suggestions...
I got those in mind(and they got rejected), but the issue is much more complex...
It is even preferred not to have the file written to the disk since it contains sensitive information.
Maybe some sort of FUSE filesystem...
The solution for now is cron job + encrypted filesystem, but I wanted to see if anyone found something else.
- WhatsHisName
- Posts: 1549
- Joined: 2005/12/19 20:21:43
- Location: /earth/usa/nj
Re: Automatically execute a program when file is written
Yes, that sounds like a job for [url=http://en.wikipedia.org/wiki/Tmpfs]tmpfs[/url].
Based on your "client requirements", the issue seems to be more about volatile storage than timeliness of execution, which makes it easier to address.
Based on your "client requirements", the issue seems to be more about volatile storage than timeliness of execution, which makes it easier to address.
Re: Automatically execute a program when file is written
This might be another option.
Just not sure about the size of the files... but is it worth considering.
Thanks,
Just not sure about the size of the files... but is it worth considering.
Thanks,
Re: Automatically execute a program when file is written
I would use auditd to monitor that folder for file creation then swatch to monitor the auditd log and trigger an event when something comes up
its a two step process but very configurable
its a two step process but very configurable
Re: Automatically execute a program when file is written
You can use the inotify mecanism that can be setup to monitor files or directory...
Search for incrond or incrontab, can't remember he exact name. I use it to execute a script whenever a file is created or moved to a specific directory...
Search for incrond or incrontab, can't remember he exact name. I use it to execute a script whenever a file is created or moved to a specific directory...
Re: Automatically execute a program when file is written
[code]
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <linux/inotify.h>
int main( )
{
int length, i = 0;
int fd;
int wd;
char buffer[EVENT_BUF_LEN];
fd = inotify_init();
if ( fd < 0 ) {
perror( "inotify_init" );
}
wd = inotify_add_watch( fd, "/YOUR/DIRECTORY", IN_CREATE | IN_DELETE );
length = read( fd, buffer, EVENT_BUF_LEN );
if ( length < 0 ) {
perror( "read" );
}
while ( i < length ) { struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ]; if ( event->len ) {
if ( event->mask & IN_CREATE ) {
if ( event->mask & IN_ISDIR ) {
printf( "New directory %s created.\n", event->name );
}
else {
printf( "New file %s created.\n", event->name );
}
}
else if ( event->mask & IN_DELETE ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s deleted.\n", event->name );
}
else {
printf( "File %s deleted.\n", event->name );
}
}
}
i += EVENT_SIZE + event->len;
}
inotify_rm_watch( fd, wd );
}
[/code]
Change /YOUR/DIRECTORY to the directory you want to monitor. Instead of printf you can do whatever, you can probably remove the delete option too.
With inotify you really need to write your own code, with auditd and swatch you don't.
[Moderator edited to insert [i]code[/i] tags to preserve the formatting.]
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <linux/inotify.h>
int main( )
{
int length, i = 0;
int fd;
int wd;
char buffer[EVENT_BUF_LEN];
fd = inotify_init();
if ( fd < 0 ) {
perror( "inotify_init" );
}
wd = inotify_add_watch( fd, "/YOUR/DIRECTORY", IN_CREATE | IN_DELETE );
length = read( fd, buffer, EVENT_BUF_LEN );
if ( length < 0 ) {
perror( "read" );
}
while ( i < length ) { struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ]; if ( event->len ) {
if ( event->mask & IN_CREATE ) {
if ( event->mask & IN_ISDIR ) {
printf( "New directory %s created.\n", event->name );
}
else {
printf( "New file %s created.\n", event->name );
}
}
else if ( event->mask & IN_DELETE ) {
if ( event->mask & IN_ISDIR ) {
printf( "Directory %s deleted.\n", event->name );
}
else {
printf( "File %s deleted.\n", event->name );
}
}
}
i += EVENT_SIZE + event->len;
}
inotify_rm_watch( fd, wd );
}
[/code]
Change /YOUR/DIRECTORY to the directory you want to monitor. Instead of printf you can do whatever, you can probably remove the delete option too.
With inotify you really need to write your own code, with auditd and swatch you don't.
[Moderator edited to insert [i]code[/i] tags to preserve the formatting.]
Re: Automatically execute a program when file is written
If you want an example written in BASH, I run this script from a cron to monitor a directory for changes and email me when there is one. It will detect if anyone creates a file or touches an existing file. Schedule the script to run every $MYFREQUENCY minutes. All it's really doing is executing a find command to look for files that have their access time changed in the last 5 minutes, and if it finds one, use mutt to send an email. I'm sure there's many better/quicker/sexier ways to do this...
[code]
#!/bin/bash
# Description: This script monitors $MYDIR (checking once every $MYFREQUENCY minutes) for
# files that have recently been created or modified, and if it finds one, it sends a logger
# message to LOGHOST, and/or an email to $MYEMAIL.
MYDIR=/dir/to/monitor
MYEMAIL='username@domain.com'
MYFREQUENCY='-5'
MESSAGEFILE="message.txt"
MYDATE=$(date +%y-%m-%d)
MYTIME=$(date +%H:%M)
MAILER=$(which mutt)
MYNAME=$(hostname)
MYSUBJECT="Data Changed in $MYDIR directory on host ${MYNAME}"
if [[ ! -f ${MAILER} ]] ; then
echo "Program \"mutt\" is required, but is not available on this host. Please install mutt package and try again."
exit 1
fi
FILECOUNT="$(find ${MYDIR} -mmin ${MYFREQUENCY} -type f | wc -l)"
if [ ${FILECOUNT} -gt 0 ]
then
echo "Directory ${MYDIR} on host ${MYNAME} has been modified:" >> /tmp/${MESSAGEFILE}
echo "Filename : Timestamp : Size in bytes" >> /tmp/${MESSAGEFILE}
find $MYDIR -mmin ${MYFREQUENCY} -type f -printf '%p : %Ac : %s bytes *** ' >> /tmp/${MESSAGEFILE}
logger -p local0.info "CHANGE DETECTED: $(cat /tmp/${MESSAGEFILE})"
cat /tmp/${MESSAGEFILE} | mutt -s "CHANGED DETECTED in host ${MYNAME}" -a /tmp/${MESSAGEFILE} ${MYEMAIL}
/bin/rm -f /tmp/${MESSAGEFILE}
fi
exit 0
[/code]
[Moderator edited to insert [i]code[/i] tags to preserve the formatting.]
[code]
#!/bin/bash
# Description: This script monitors $MYDIR (checking once every $MYFREQUENCY minutes) for
# files that have recently been created or modified, and if it finds one, it sends a logger
# message to LOGHOST, and/or an email to $MYEMAIL.
MYDIR=/dir/to/monitor
MYEMAIL='username@domain.com'
MYFREQUENCY='-5'
MESSAGEFILE="message.txt"
MYDATE=$(date +%y-%m-%d)
MYTIME=$(date +%H:%M)
MAILER=$(which mutt)
MYNAME=$(hostname)
MYSUBJECT="Data Changed in $MYDIR directory on host ${MYNAME}"
if [[ ! -f ${MAILER} ]] ; then
echo "Program \"mutt\" is required, but is not available on this host. Please install mutt package and try again."
exit 1
fi
FILECOUNT="$(find ${MYDIR} -mmin ${MYFREQUENCY} -type f | wc -l)"
if [ ${FILECOUNT} -gt 0 ]
then
echo "Directory ${MYDIR} on host ${MYNAME} has been modified:" >> /tmp/${MESSAGEFILE}
echo "Filename : Timestamp : Size in bytes" >> /tmp/${MESSAGEFILE}
find $MYDIR -mmin ${MYFREQUENCY} -type f -printf '%p : %Ac : %s bytes *** ' >> /tmp/${MESSAGEFILE}
logger -p local0.info "CHANGE DETECTED: $(cat /tmp/${MESSAGEFILE})"
cat /tmp/${MESSAGEFILE} | mutt -s "CHANGED DETECTED in host ${MYNAME}" -a /tmp/${MESSAGEFILE} ${MYEMAIL}
/bin/rm -f /tmp/${MESSAGEFILE}
fi
exit 0
[/code]
[Moderator edited to insert [i]code[/i] tags to preserve the formatting.]
Re: Automatically execute a program when file is written
That's neat but it's not instant, as in you can run it every minute but yeah, to get instant notification you can't beat auditd + swatch or inotify.