1

I'm trying to write a script that will restart a process when the application configuration file is written to, using inotify. The script is supposed to act differently depending on which host it is run: If it is run on a "primary" server, the script should restart the process, and scp the file to the other, "secondary" hosts. If it is run on a "secondary" server, it should just restart the process.

I run the script in the background and I noticed the script's process dies after a while, and on the secondary hosts, the scripts restart process runs a number of times, instead of just once.

    #!/bin/bash
# Script to watch APP application file for write changes.
# If APP is written to and saved, on server0, restart APP and check if its running.
# Then push to other servers with userone account.
# If not on server0, push simply restart APP.

declare -a APP_HOSTS=("server0" "server1" "server3" "pushserver0" "pushserver1" "pushserver3" "vumitest")
declare -a my_needed_commands=("/opt/APP/conf/application.conf" "inotifywait" "service")
HOSTNAME=$(hostname -s)

missing_commands()
{
    local missing_counter=0
    for needed_command in "${my_needed_commands[@]}"; do
        if ! command -v "$needed_command" >/dev/null 2>&1; then
            printf "Command not found in PATH: %s\n" "$needed_command" >&2
            ((missing_counter++))
        fi
    done

    if ((missing_counter > 0)); then
        printf "Minimum %d commands are missing in the PATH, aborting.\n" "$missing_counter" >&2
        exit 1
    fi
}

restart_and_scp()
{
    local host_count=0
    local restofthem=("${APP_HOSTS[@]}")
    unset restofthem[0]
    if service APP restart >/dev/null 2>&1; then
        for each in "${restofthem[@]}"; do
            scp -Cqv "${my_needed_commands[0]}" userone@"$each":/opt/APP/conf >/dev/null 2>&1
            ((host_count++))
            if [ host_count -eq "${#restofthem[@]}" ]; then
                break
            fi
        done
    fi
}

restart_APP()
{
    service APP restart >/dev/null 2>&1
}

prime_watch()
{
    inotifywait -mrq -e close_write "${my_needed_commands[0]}" | \
    while read filename; do restart_and_scp; done
}

other_watch()
{
    inotifywait -mrq -e modify "${my_needed_commands[0]}" | \
    while read filename; do restart_APP; done
}

setup_watch()
{
    if [ ! -z "$1" ]; then
        prime_watch 
    else
        other_watch
    fi
}

main()
{

    if [[ "${APP_HOSTS[0]}" =~ "${HOSTNAME}" ]]; then 
        setup_watch prime
    else
        setup_watch
    fi 
    exit
}

main "$@"

Please what am I doing wrong?

  • At first blush, I would guess that your inotifywait loops are exiting; add a logging entry at the end of prime_watch and other_watch. For the secondary multiple-restarts, perhaps you're getting more than one inotify result when you're only expecting one? Perhaps add some logging of the inotify activity inside your while/read loop (next to the restart/scp or restart_app) to pin it down. – Jeff Schaller Aug 6 '17 at 2:34
  • HI Jeff. Thanks for responding. What kind of logging entry? Does inotify have a logging aspect to it? – SinaOwolabi Aug 6 '17 at 8:16
  • just printf something to a log file; something along the lines of printf "%s: %s - %s\n" >> /tmp/prime_log "$(date)" "prime_watch" "message here" – Jeff Schaller Aug 6 '17 at 11:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.