简体   繁体   中英

Executing a bash script upon file creation

I am looking write a small bash script to, when launched, watch a directory for any newly created files. If a new file appears, I want its presence to trigger a second script to run.

I see this being used to trigger the compression recently digitized video, and add it to a log of ingested footage.

Currently my code looks like this:

#!/bin/sh

##VIDSTAT is a global variable coming from a parent script.
##proj is the ingestion directory coming from a parent script
proj=$1

dir="/home/$USER/data/movies/$proj"
dirlist=$(ls $dir)


while { $VIDSTAT -eq 1 }:
do
    for mov in $dirlist
    do
        if [ "$(( $(date +"%s") - $(stat -c "%Y" $mov) ))" -lt "5" ]
        then
        ~/bin/compressNlog.sh $mov
        fi
    done
done

Is there an easier/cleaner/less memory intensive way to do this?

EDIT I will be changing the ingestion directory per capture session. I have adjusted the code accordingly

How about incron ? It triggering Commands On File/Directory Changes.

sudo apt-get install incron

Example:

<path> <mask> <command>

Where <path> can be a directory (meaning the directory and/or the files directly in that directory (not files in subdirectories of that directory!) are watched) or a file.

<mask> can be one of the following:

IN_ACCESS           File was accessed (read) (*)
IN_ATTRIB           Metadata changed (permissions, timestamps, extended attributes, etc.) (*)
IN_CLOSE_WRITE      File opened for writing was closed (*)
IN_CLOSE_NOWRITE    File not opened for writing was closed (*)
IN_CREATE           File/directory created in watched directory (*)
IN_DELETE           File/directory deleted from watched directory (*)
IN_DELETE_SELF           Watched file/directory was itself deleted
IN_MODIFY           File was modified (*)
IN_MOVE_SELF        Watched file/directory was itself moved
IN_MOVED_FROM       File moved out of watched directory (*)
IN_MOVED_TO         File moved into watched directory (*)
IN_OPEN             File was opened (*)

<command> is the command that should be run when the event occurs. The following wildards may be used inside the command specification:

$$   dollar sign
$@   watched filesystem path (see above)
$#   event-related file name
$%   event flags (textually)
$&   event flags (numerically)

If you watch a directory, then $@ holds the directory path and $# the file that triggered the event. If you watch a file, then $@ holds the complete path to the file and $# is empty.

Working Example:

$sudo echo spatel > /etc/incron.allow
$sudo echo root > /etc/incron.allow

Start Daemon:

$sudo /etc/init.d/incrond start

Edit incrontab file

$incrontab -e
/home/spatel IN_CLOSE_WRITE touch /tmp/incrontest-$#

Test it

$touch /home/spatel/alpha

Result:

$ls -l /tmp/*alpha*
-rw-r--r-- 1 spatel spatel 0 Feb  4 12:32 /tmp/incrontest-alpha

Notes: In Ubuntu you need to activate inotify at boot time. Please add following line in Grub menu.lst file:

kernel /boot/vmlinuz-2.6.26-1-686 root=/dev/sda1 ro inotify=yes

You can do this with the magical inotify tool :

inotifywait -r -m ./YOUR_MONITORED_DIR |
    while read a b file; do
        [[ $b == *CREATE* ]] && ./another_script "$file"
    done

This method have the big advantage to avoid polling every N seconds.

Inotify (inode notify) is a Linux kernel subsystem that acts to extend filesystems to notice changes to the filesystem, and report those changes to applications. It replaces an earlier facility, dnotify, which had similar goals.

http://en.wikipedia.org/wiki/Inotify
See inotify doc

Use iwatch . No, really. It'll handle all of the details of making a daemon, running on startup, monitor and log, so on and so on. All you need to do is set the options, and have your bash script handle the details of actually doing something with the file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM