I'm trying to make a inotifywait script take different actions for files vs folders if it sees a close_write flag being raised in the watched directory, but cannot seem to get the checks working.

In other scripts I use these kinds of checks all the time and they just_work, but there seems to be something about inotifywait I'm not grasping yet.

This is the script in its current form:



    while true; do
     inotifywait -r -e close_write "$dir1" | while read f; do
      echo $f
      #Is it a directory?
      if [[ -d "${f}" ]]; then
       echo "New directory called ${f} detected"
       chown -R jake:jake $f
       chmod -R 775 $f
       cp -R $f /media/lacie/Film
      #Is it a file?
      if [[ -f "${f}" ]]; then 
      echo "New file called ${f} detected"
      chown jake:jake $f
      chmod 775 $f
      cp $f /media/lacie/Film


If I run this in a terminal to see what is happening all I get is the confirmation a close_write was detected, followed by a "setting up watches" without any other messages or any of the other code being triggered, not even the debug echo directly below:

 while read f; do


I'm running this on Ubuntu server 12.04 LTS 64 bit.

$ bash --version
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)

$ dpkg -l | grep inotify
ii  inotify-tools                    3.13-3
ii  libinotifytools0                 3.13-3
ii  python-pyinotify                 0.9.2-1

$ python --version
Python 2.7.3

2 Answers 2


The following works for me:


Below shows an example of inotifywait using a method similar to your own.

$ inotifywait -r -e close_write "somedir" | while read f; do echo "$f hi";done
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.    

I then go into the directory somedir and touch afile, touch afile. Which results in this occurring in the inotifywait window:

somedir/ CLOSE_WRITE,CLOSE afile hi

NOTE: To get all the output from inotifywait you could modify your example slightly:

$ inotifywait -r -e close_write "somedir" 2>&1 | \
    while read f; do echo "$f | hi";done
Setting up watches.  Beware: since -r was given, this may take a while! | hi
Watches established. | hi

And again touch a file with the command, touch afile, I now see the event:

somedir/ CLOSE_WRITE,CLOSE afile | hi

For another example that shows how to use inotifywait take a look at the example I showed in my answer to this Q&A titled: Automatically detect when a file has reached a size limit.

Your issue

I believe part of your issue is that you're assuming that the output returned from inotifywait is just the file's name while clearly it isn't from the above examples.

So these if statements will never succeed:

  if [[ -d "${f}" ]]; then


  if [[ -f "${f}" ]]; then 

When developing Bash scripts such as this it's often helpful to enable debugging messages via this command at the top:

set -x

You can disable it with this:

set +x

You can wrap sections of your code using these messages to turn it on/off.

set -x
set +x
  • Thanks for pointing out the debug option in bash, i did not know about this and it will help me a lot in the future.
    – Jake
    Commented May 31, 2014 at 0:46

Got it working thanks to the info slm provided :-)


# Written by Jan Duprez and licensed as
# do whatever you want with this but don't come whining
# if you somehow manage to trash your system with it.
# You pressed the buttons, remember?

# This script uses inotifywait to watch a directory and copies
# files or directories moved into it to another folder.

# The commandline parameters are:
# 1 - Directory to watch
# 2 - Directory where new file/folder is copied to
# 3 - UID to use to chmod the file/folder in BOTH dirs
# 4 - GID to use to chmod the file/folder in BOTH dirs
# 5 - permissions to set for the new file/folder in BOTH dirs


# Check if commandline parameters are all there, show reminder if not
if [[ -z $dir1 || -z $dir2 || -z $user || -z $group || -z $perms ]];
    echo -e "Please provide a source dir as 1st parameter"
            echo -e "Please provide a dest dir as 2nd parameter"
            echo -e "Please provide a UID as 3rd parameter"
            echo -e "Please provide a GID as 4th parameter"
            echo -e "Please provide a file permission string (ex 755) as 5th parameter"

# Good to go, start watching
while true; do

#add -e close_write and -e create for testing
inotifywait -r -e move "$dir1" | while read f; do

#Get part after inotify triggers with awk, remove leading spaces with sed
new=`echo $f | awk '{$1=$2=""; print $0}' | sed 's/^ *//'`
#And the preconstruded full path to avoid ugly buggery between the  [[ ]]    test

    if [[ -d "${test}" ]] ; then
    chown -R $user:$group "$dir1$new"
    chmod -R $perms "$dir1$new"
    cp -R "$dir1$new" "$dir2"
    chown -R $user:$group "$dir2$new"

    if [[ -f "${test}" ]] ; then
    chown $user:$group "$dir1$new"
    chmod $perms "$dir1$new"
    cp "$dir1$new" "$dir2"
    chown $user:$group "$dir2$new"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .