8

watch command to notify on newly created files on linux

How to modify the below command to notify on creating a new file to /usr/local/mydir/ by linux user john ?

watch -d 'ls -l /usr/local/mydir/ | fgrep john'

ie I want to continually monitor and call an another script if any new file is created to /usr/local/mydir/.

As In production I cannot go for any tool instead of shell script. So can help me with shell scripting solution ?

Aha
  • 409
  • 3
  • 8
  • 18

3 Answers3

9

Instead of constantly pulling a directory this way, maybe try to use the inotify subsystem, which is designed for this purpose. For user space tools, have a look at the inotify-tools.

Sven
  • 98,649
  • 14
  • 180
  • 226
6

inotify suggested by SvenW is an excellent choice for this.

Just to be different: Alternative, more complete way for this kind of stuff is to use kernel audit subsystem and auditd. Just install auditd if it's not already installed and then use auditctl, in your case

auditctl -w /usr/local/mydir/ -p wa -F uid=john -k johnschangedfiles

would do.

Then you can run a report and see a very detailed log of what happened and when:

ausearch -f /usr/local/mydir/

This produces results similar to this:

time->Fri Feb  3 12:45:19 2012
type=PATH msg=audit(1328265919.961:11): item=0 name="/tmp/test/foo" inode=1839907 dev=fd:00 mode=0100664 ouid=500 ogid=500 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0
type=CWD msg=audit(1328265919.961:11):  cwd="/tmp"
type=SYSCALL msg=audit(1328265919.961:11): arch=c000003e syscall=2 success=yes exit=3 a0=7fffa6f4262e a1=941 a2=1b6 a3=3136fb0d0c items=1 ppid=12414 pid=23531 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=686 comm="touch" exe="/bin/touch" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="jpikkschangedfiles"
Janne Pikkarainen
  • 31,852
  • 4
  • 58
  • 81
2

If you insist on using just standard tools, a script like the following might help:

#!/bin/bash
ls -l /usr/local/mydir | grep john > /tmp/watchfile

while true; do
   sleep 10
   ls -l /usr/local/mydir | grep john > /tmp/watchfile2
   diff -q /tmp/watchfile /tmp/watchfile2 > /dev/null
   if [ $? -ne 0 ] ; then
       echo "File list changed" 
       exit ;
   fi
   cp /tmp/watchfile2 /tmp/watchfile
done

Replace the echoline with your desired action and remove the exit line if you want to run this script continuously.

Note: This will act on any modification of the directory listing, even if files just get updated, not added.

Sven
  • 98,649
  • 14
  • 180
  • 226
  • Thanks fro your response ... But if any file get deleted from [/usr/local/mydir] this also will differ the watchfile and watchfile2. I want to do the desired action only when the new file is created in [/usr/local/mydir]. – Aha Feb 03 '12 at 13:31
  • 1
    Yes. Getting this right and fitting for every situation is difficult (but possible). Therefore, I again suggest to use tools that are designed for this purpose. – Sven Feb 03 '12 at 13:35