6

I have a script that watches a directory (recursively) and performs a command when a file changes. This is working correctly when the monitoring flag is used as below:

#!/bin/sh

inotifywait -m -r /path/to/directory |
    while read path action file; do
            if [ <perform a check> ]
            then
                my_command
            fi
    done

However, I want to run this on startup and in the background, so naïvely thought I could change the -m flag to -d (run inotifywait as daemon, and include an --outfile location) and then add this to rc.local to have this run at startup. Where am I going wrong?

Nicholas
  • 546
  • 1
  • 6
  • 19
  • 1
    in your `/etc/rc.local` file, did you call the script with a single `&` at the end? – Jebby Jan 16 '18 at 00:32
  • @Jebby - this is exactly what I needed to do. Thanks! Running inotifywait as daemon was a red herring, as was pointed out by tink below the code was never run. If you set this as an answer, I will mark it as the correct one. – Nicholas Jan 16 '18 at 11:42
  • I have added the answer below. Glad to help! – Jebby Jan 16 '18 at 11:45

3 Answers3

5

Incron is a cron-like daemon for inotify events.

Just need to use incrontab and an entry for your task:

/path/to/directory IN_ALL_EVENTS /usr/local/bin/my-script $@ $# $%

And /local/bin/my-script would be:

#! /bin/bash
local path=$1
local action=$2
local file=$3
if [ <perform a check> ]
then
  my_command 
fi
Gonzalo Matheu
  • 8,984
  • 5
  • 35
  • 58
4

Well .... with -d it backgrounds itself and outputs ONLY to outfile, so your whole pipe & loop construct is moot, and it never sees any data.

tink
  • 14,342
  • 4
  • 46
  • 50
  • Thanks, that explains it. Does this mean that inotifywait can only log changes with the -d flag? Is it possible to trigger an action after a change occurs? – Nicholas Jan 16 '18 at 08:36
  • @Nicholas : No, it doesn't mean that. But if you specify --outfile it doesn't output anything but debug info to standard output. If you want to interact with the output **AND** have a log just use tee ... ` inotifywait -m -r /path/to/directory | tee -a ~/notify | while ... ` – tink Jan 16 '18 at 21:25
  • ah I see, that makes much more sense now. I achieved what I needed above, but using the inotifywait daemon flag would be a more elegant solution. I will give this a go using tee. Thank you very much for your help! – Nicholas Jan 17 '18 at 17:39
  • Most welcome. You could split processing up, daemonise inotifywait and have the log being read in a second step, but that would introduce a) more complexity and b) potential timing issues on startup. There's nothing wrong with the **KISS** approach and using tee for what it's intended for ;} – tink Jan 17 '18 at 19:27
2

You need to add a single & to the end of command in your /etc/rc.local

Putting a single & at the end of a command means Run this program in the background so the user can still have input.

Jebby
  • 1,845
  • 1
  • 12
  • 25