McDowells
McDowells

Reputation: 98

Script to monitor directory for creation of a file and modify the file

When files specifically named xxx.java and yyy.java get downloaded into my Downloads folder I want to automatically patch them in the background transparently using my diff files.

I have tried monitoring the directory using ls but the next step is difficult:-

#! /usr/bin/env bash

MONITOR_DIR=/home/hduser/Downloads
set x = 1
while : ; do
   cur_files=$(ls ${MONITOR_DIR})
   for i in cur_files
      { 
         if[ "$i" = "xxx.java" ]; then      
          patch $i < foo.patch
          set x = 0
         fi
         if[ "$i" = "yyy.java" ];then
          patch $i < bar.patch
          if [ "$x" eq 0];then break; fi    #doesn't work

         fi
     }

     sleep 4
done

Upvotes: 0

Views: 201

Answers (2)

thom
thom

Reputation: 2332

I'll make it easy on you, this one is a no brainer:

#!/bin/bash

MONITOR_DIR="/home/hduser/Downloads"
PATCHES="/path/where/the/patches/are"  

GoPatch()    { patch "$MONITOR_DIR/$1" < "$PATCHES/$2" ;}    

inotifywait -q -m -e close_write "$MONITOR_DIR" |\
while read _DUMMY DUMMY FILENAME
do
    case "$FILENAME" in
    "xxx.java" ) [ $xflag ] || { xflag=x ; GoPatch xxx.java foo.patch ;} ;; 
    "yyy.java" ) [ $yflag ] || { yflag=x ; GoPatch yyy.java bar.patch ;} ;; 
    "zzz.java" ) [ $zflag ] || { zflag=x ; GoPatch zzz.java bof.patch ;} ;; 
    esac
done

Before the patch, we disable the followed path by setting a flag so patching only occurs once per file.

Upvotes: 0

thom
thom

Reputation: 2332

Don't poll ! Use inotifywait.

#!/bin/bash

MONITOR_DIR="/home/hduser/Downloads"
PATCHED_DIR="/path/where/the/patched/files/are/moved/to"
PATCHES="/path/where/the/patches/are"  

inotifywait -q -m -e close_write "$MONITOR_DIR" |\
while read _DUMMY DUMMY FILENAME
do
    case "$FILENAME" in
    "xxx.java" ) patch="foo.patch" ;; 
    "yyy.java" ) patch="bar.patch" ;; 
    "zzz.java" ) patch="qqq.patch" ;;
    esac

    mv "$MONITOR_DIR/$FILENAME $PATCHED_DIR/$FILENAME"
    patch "$PATCHED_DIR/$FILENAME" < "$PATCHES/$patch" &
done

Inotifywait will sleep until woken up by the OS if a file is written in the directory,
it will output watched_filename EVENT_NAMES event_filename
(we will only use event_filename which we read via pipe into FILENAME).

By using the case statement, we select a patch.

Then we move the file to another dir and start patching it there (in the background). While the patching starts we are immediatley ready to wait (sleeping) for the next file.

(oh, and don't forget that the |\ must NOT be followed by space or something else)

Upvotes: 2

Related Questions