Home > OS >  inotifywait ignore while loop
inotifywait ignore while loop

Time:06-28

I am having trouble with using inotifywait properly.

My environment is CentOS 8 Stream with i7-9700

test.sh

#!/bin/bash

inotifywait -e modify ./test.txt |
while read dirname eventlist filename
do
  echo "Event catch!"
done

echo "I am doing next thing"

output in terminal(stdout)

[root@ceph examples]# sh test.sh
Setting up watches.
Watches established.
I am doing next thing

What I expect?

I expect that my script print the line, "Event catch!". As you can see, my bash script ignore all while loop block and just print "I am doing next thing".

CodePudding user response:

The normal behavior of inotifywait is to exit after it has captured an event.

If you want inotifywait to keep monitoring events, you have to use the -m option switch.

Also in your script, you read 3 arguments from the output if inotifywait whereas only 2 might be returned if it has a single event. You may use the --format option to keep a predictable output format.

#!/bin/sh

inotifywait -m -e modify ./test.txt |
while read -r filename eventlist
do
  printf 'Event catch!\nfilename=%s, eventlist=%s\n' "$filename" "$eventlist"
done

printf %s\\n "I am doing next thing"

If you want to exit inotifywait, you just kill the parent process from the pipe.

Example:

#!/bin/sh

max_events=2
inotifywait -m -e modify ./test.txt |
while read -r filename eventlist
do
  printf 'Event catch!\nfilename=%s, eventlist=%s\n' "$filename" "$eventlist"
  max_events=$((max_events - 1))
  [ 0 -eq "$max_events" ] && kill $$
done

printf %s\\n "I am doing next thing"

And now with Bash arrays for events and reading a controlled format:

#!/bin/bash

max_events=2
while
  # Reads file name
  read -r -d '' filename &&
  # and reads event list in an array
  read -r -a eventlist
do
  declare -p filename eventlist
  printf 'Event catch!\nfilename! %s\neventlist: %s\n' "$filename" \
    "${eventlist[*]}"
  ((--max_events)) || break
done < <(
  inotifywait --format '%w%0%e' --monitor --event MODIFY ./test.txt
)

printf %s\\n "I am doing next thing"
  • Related