Search code examples
bashubuntusupervisordinotifywait

inotifywait is not killed with supervisorctl stop


I have this bash script running with supervisor

#!/bin/bash
DIR="/home/files"
while read file; do
   IFS=', ' read -r -a array <<< "$file"
   echo "Time: ${array[0]}"
   echo "File: ${array[1]}"
   #... doing something with the file
done < <(inotifywait -m -r -e close_write  "$DIR" --timefmt "%d_%b_%Y" --format "%T %w%f")

It runs just fine, but when I do supervisorctl stop all, even though program stops, the inotifywait process keeps running. Is there a way to kill the inotifywait once the bash script exits?

Edit 1 Supervisor config for this program is

[program:watch]
command=/root/watch_data.sh
user=root
stderr_logfile=/var/log/supervisord/watch_cloud.log
stdout_logfile=/var/log/supervisord/watch_cloud.log
autorestart=true
stopsignal=INT

Solution

  • I think you are missing an option to propagate the kill signal to all the child processes when you do supervisorctl stop all. Usually one has a parent process and children, when the parent gets SIGTERM/SIGINT it will/should have a coordinated way and should be the one in charge of sending signals or by other means shutting down the children.

    The supervisord provides just an option for that. From the official documentation

    stopasgroup

    If true, the flag causes supervisor to send the stop signal to the whole process group and implies killasgroup is true. This is useful for programs, such as Flask in debug mode, that do not propagate stop signals to their children, leaving them orphaned.

    killasgroup

    If true, when resorting to send SIGKILL to the program to terminate it send it to its whole process group instead, taking care of its children as well, useful e.g with Python programs using multiprocessing.

    The killasgroup kills all processes in the group when Supervisor resorts to sending a SIGKILL. The idea is that when the process is playing nicely, it should be allowed to handle stopping it's children on its own. But when it misbehaves and needs an option for force the whole process group to termination.

    Also remember propagating SIGINT, though the default action is to terminate gracefully can be ignored by processes. If you are not worried too much about graceful termination of the script, you can pass SIGKILL which is the equivalent of signal generated by kill -9 in Linux.

    So the following options in your supervisor config file

    [program:watch]
    command=/root/watch_data.sh
    user=root
    stderr_logfile=/var/log/supervisord/watch_cloud.log
    stdout_logfile=/var/log/supervisord/watch_cloud.log
    stopasgroup=true
    killasgroup=true
    stopsignal=KILL