6

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
  • 72,312
fixit7
  • 3,399

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,885
2

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
  • 153
0

This kills all the instances of inotifywait:

pkill inotifywait
Eliah Kagan
  • 119,640
Niru
  • 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