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"