Himmators
Himmators

Reputation: 15006

How can I run multiple inotifywait loops in Bash?

I have a script that ran as a daemon listening to a file:

#!/bin/bash
echo '1'
while inotifywait -e close_write /home/homeassistant/.homeassistant/automations.yaml
do
    echo 'automations'
    curl -X POST -H "x-ha-access: pass" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/automation/reload
done;

I wanted to listen to several files, and tried adding two more loops:

while inotifywait -e close_write /home/homeassistant/.homeassistant/groups.yaml
do
    echo 'gropus'
    curl -X POST -H "x-ha-access: pass" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/group/reload
done;

while inotifywait -e close_write /home/homeassistant/.homeassistant/core.yaml
do
    echo 'core'
    curl -X POST -H "x-ha-access: pass" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/homeassistant/reload_core_config
done;

I realized that the first loop never gets closed so the other ones never get started, but not sure how I should solve this.

Upvotes: 3

Views: 1436

Answers (1)

chepner
chepner

Reputation: 531165

You need to run the first loop in a background process so that it doesn't block your script. You may want to run each loop in the background for symmetry, then wait on them at the end of the script.

while inotifywait -e close_write /home/homeassistant/.homeassistant/groups.yaml
do
    echo 'gropus'
    curl -X POST -H "x-ha-access: pass" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/group/reload
done &

while inotifywait -e close_write /home/homeassistant/.homeassistant/core.yaml
do
    echo 'core'
    curl -X POST -H "x-ha-access: pass" -H "Content-Type: application/json" http://hassbian.local:8123/api/services/homeassistant/reload_core_config
done &

wait

However, you can run inotifywait in monitor mode and monitor multiple files, piping its output into a single loop. (Caveat: like any line-oriented output format, this cannot cope with filenames containing newlines. See the --format and --csv options for dealing with filenames containing whitespace.)

files=(
  /home/homeassistant/.homeassistant/groups.yaml
  /home/homeassistant/.homeassistant/core.yaml
)

take_action () {
    echo "$1"
    curl -X POST "x-ha-access: pass" -H "Content-Type: application/json" \
      http://hassbian.local:8123/api/services/"$2"
}

inotifywait -m -e close_write "${files[@]}" |
  while IFS= read -r fname _; do
    case $fname in
      */groups.yaml) take_action "groups" "group/reload" ;;
      */core.yaml)   take_action "core" "homeassistant/reload_core_config" ;;
    sac
  done

Upvotes: 7

Related Questions