Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

inotify and bash

Tags:

bash

inotify

I am trying to make a bash script with inotify-tools that will monitor a directory and alter all new files by removing lines containing "EE". Once altered it will move the files to another directory

    #!/bin/sh     while inotifywait -e create /home/inventory/initcsv; do       sed '/^\"EE/d' Filein > fileout #how to capture File name?       mv fileout /home/inventory/csvstorage     fi     done 

Please help?

like image 912
user963091 Avatar asked Sep 24 '11 22:09

user963091


People also ask

What is inotify in Linux?

inotify (inode notify) is a Linux kernel subsystem created by John McCutchan, which monitors changes to the filesystem, and reports those changes to applications. It can be used to automatically update directory views, reload configuration files, log changes, backup, synchronize, and upload.

What is inotify wait?

Description. inotifywait efficiently waits for changes to files using Linux's inotify(7) interface. It is suitable for waiting for changes to files from shell scripts. It can either exit once an event occurs, or continually execute and output events as they occur.

What is inotify Ubuntu?

DESCRIPTION. The inotify API provides a mechanism for monitoring filesystem events. Inotify can be used to monitor individual files, or to monitor directories.


2 Answers

By default, the text output from inotifywait -e CREATE is of form

     watched_filename CREATE event_filename 

where watched_filename represents /home/inventory/initcsv and event_filename represents the name of the new file.

So, in place of your while inotifywait -e ... line, put:

    DIR=/home/inventory/initcsv     while RES=$(inotifywait -e create $DIR); do         F=${RES#?*CREATE } 

and in your sed line use $F as the Filein name. Note, the $(...) construction is posix-compatible form of process substitution (often done using backticks) and the ${RES#pattern} result is equal to $RES with the shortest pattern-matching prefix removed. Note, the last character of the pattern is a blank. [See update 2]

Update 1 To handle file names that may contain whitespace, in the sed line use "$F" instead of $F. That is, use double quotes around the reference to value of F.

The RES=... and F=... definitions do not need to use double quotes, but it is ok to use them if you like; for example: F=${RES#?*CREATE } and F="${RES#?*CREATE }" both will work ok when handling filenames containing whitespace.

Update 2 As noted in Daan's comment, inotifywait has a --format parameter that controls the form of its output. With command

while RES=$(inotifywait -e create $DIR --format %f .)    do echo RES is $RES at `date`; done 

running in one terminal and command

touch a aa; sleep 1; touch aaa;sleep 1; touch aaaa 

running in another terminal, the following output appeared in the first terminal:

Setting up watches. Watches established. RES is a at Tue Dec 31 11:37:20 MST 2013 Setting up watches. Watches established. RES is aaa at Tue Dec 31 11:37:21 MST 2013 Setting up watches. Watches established. RES is aaaa at Tue Dec 31 11:37:22 MST 2013 Setting up watches. Watches established. 
like image 59
James Waldby - jwpat7 Avatar answered Sep 25 '22 02:09

James Waldby - jwpat7


The output from inotifywait is of the form:

filename eventlist [eventfilename] 

If your file names can contain spaces and commas, this gets tricky to parse. If it only contains 'sane' file names, then you can do:

srcdir=/home/inventory/initcsv tgtdir=/home/inventory/csvstorage inotifywait -m -e create "$directory" | while read filename eventlist eventfile do     sed '/^"EE/d'/' "$srcdir/$eventfile" > "$tgtdir/$eventfile" &&     rm -f "$srcdir/$eventfile done 
like image 24
Jonathan Leffler Avatar answered Sep 25 '22 02:09

Jonathan Leffler