5

I made a script to invoke inotifywait. It works fine, but I sometimes want to stop it.

How do I stop the last inotifywait instance?

I cannot understand how to use inotify_rm_watch which I understand is used to close it.

7341 ?        S      0:00 inotifywait -m /home/andy/Downloads/ --format %w
Zanna
  • 69,223
  • 56
  • 216
  • 327
fixit7
  • 2,776
  • 3
  • 30
  • 70

4 Answers4

3

The inotify_rm_watch you refer to is the API (C-function) you would use when writing a "real" program (in C or something similar), not a script. So it doesn't apply to your situation.

If you want to stop inotifywait you can do it as with any other program:

  • Either issue ps -ef | grep inotifywait, pick the PID (in your example presumably 7341) and then send it a signal:

    kill 7341

  • Or use the convenience script killall which kills all programs with a given name. killall is usually installed by default.

    killall inotifywait

PerlDuck
  • 13,014
  • 1
  • 36
  • 60
  • Thanks for your help. My question was in response to a need to find files that I have created. Sometimes I forget where I save them. I would like something that could find files created withing the last 5 minutes. What do you think of this ? find /home/andy/Downloads -iname "*.png" -mmin -5 -print – fixit7 Jan 11 '18 at 02:55
  • @fixit7 AU has means to express gratitude. Please see [_What should I do when someone answers my question?_](https://askubuntu.com/help/someone-answers) But don't hurry, take your time. /// Your `find` looks good, but actually it is a completely new question that has nothing to do with `inotifywait`. See [here](https://stackoverflow.com/q/8347359/5830574), for example, for a similar question on [so]. – PerlDuck Jan 11 '18 at 10:34
  • Don't get me wrong, I didn't want to push you. You can always change your mind when a better answer appears tomorrow or next month. I just wanted to say that accepting and/or up (or down)voting is the way to say "Thank you" here. – PerlDuck Jan 11 '18 at 17:48
  • I don't feel pushed. Hope you have a great day. :-) – fixit7 Jan 11 '18 at 19:19
1

WHAT IS THE PROBLEM WHEN USING kill <pid>?

You might have more than one inotifywait processes because other scripts can use inotifywait independently. So using this command ps -ef | grep inotifywait to find the right PID is not the best thing to do because you need to have a good assumption which inotifywait process belongs to your script. So, you might end up killing the wrong PID. Besides, the command killall inotifywait is more aggressive than the previous one. However, if you really don't care other system is using inotifywait, you use the aggressive command.

MY BEST WAY TO KILL inotifywait PROCESS FOR EACH inotifywait instance

You can create a file flag to terminate inotifywait for a specific running script. Below scripts is example how you start the inotify script, stop it, or even test if it's running for that specific inotify PID.

#!/bin/bash
# inotify-test.sh
test="changes.txt" # Monitoring file
flag="flag.txt" # For stopping, starting event or whatever flag you need
REPORT_FILE="report.txt"
cat /dev/null > $REPORT_FILE
pid="inotify-test.pid"
cat /dev/null > $max_pid
ARGS1="$1"

function start_monitor {

# If file not exist, then write default start
if [ -f "${flag}" ]; then
        echo "start" > "${flag}"
fi
# Do not use -q -q (twice), because it will not output anything after do while loop
(echo "$BASHPID" > $pid; exec inotifywait -q $flag $test -e modify -m) |
while read file action
do
        process_flag=$(head -1 ${flag})
        if [ "${process_flag}" == "stop" ]; then
                echo "Process stopped" >> $REPORT_FILE
                kill -- -$$
        elif [ "${process_flag}" == "sleep" ]; then
                echo "Process sleep: $$" >> $REPORT_FILE
                sleep 5
                # Important, after sleep, must write start to start
                echo "start" > "${flag}"
        elif [ "${process_flag}" == "start" ]; then
                echo "Process is running" >> $REPORT_FILE
                # Only run here if flag is start
                echo "File: $file, action: $action, date `date`" >> $REPORT_FILE
        else
                echo "Invalid flag $$" >> $REPORT_FILE
        fi
done & # This symbol & is important, it will run this inotify in background

}

if [ "${ARGS1}" == "start" ]; then
        start_monitor
fi

if [ "${ARGS1}" == "stop" ]; then
        echo "stop" > "${flag}"
fi

if [ "${ARGS1}" == "test" ]; then
        echo "sleep" > "${flag}"
fi

You can watch this action from the log file $REPORT_FILE

tail -f report.txt

To start monitoring, you can use:

./inotify-test.sh start

To test the script with if inotifywait is running you do this command:

./inotify-test.sh test

So, to stop the inotify running process, you just need to run the same script with

./inotify-test.sh stop

With this method, you don't need to know what is the process ID for that inotifywait process.

HOW DOES IT WORK?

You notice that I have 2 files to monitor $flag $test from the inotifywait command so if I make changes to the $flag file, the modify even will be triggered immediately and I can use this opportunity to stop the PID process inside the inotifywait loop. Also, you can see that the script actually stores an actual pid of inotifywait at pid="inotify-test.pid". So you can manually terminate the inotifywait process using this correct pid.

MaXi32
  • 143
  • 9
0

This kills all the instances of inotifywait:

pkill inotifywait
Eliah Kagan
  • 116,445
  • 54
  • 318
  • 493
Niru
  • 1
  • 1
0

When using inotifywait --daemon you never get the process's ID.

If you're like me and don't want to kill ALL the instances of inotifywait indiscriminately you can instead use nohup and inotifywait --monitor.

Here's how I'm using it in my bash scripts. It allows me to not disturb other running instances of inotifywait:

# Launch with nohup and redirect inputs and outputs
nohup inotifywait --monitor --outfile /out/file </dev/null >/dev/null 2>&1 &

# Gets process ID of last launched process.
_INOTIFYWAIT_PID=$!

# later on ...

# Kill only this instance of 'inotifywait'
kill ${_INOTIFYWAIT_PID}

The input and output redirection commands (</dev/null >/dev/null 2>&1 &) comes from this answer on StackOverflow