Looping on variables with a condition in bash (Starting services in a specific order)

Viewed 43

I'm creating a script in bash to perform the below use cases,

  • Finding specific services based on specific words on their names
  • Starting these services in a specific order like: service_3, service_2 and so on
  • Before starting the next service, It will make sure that the previous one is fully started and if not, It will wait (For example: 4 minutes) until it's fully started and if it's still not fully started, It will try to stop then start it, It will print out a message that the service needs an investigation and break the flow

This is my progress, Firstly, I've found the services based on some words that only exists with their names as below,

service_1=$(ls /etc/systemd/system | grep -e text1 | awk -F ' ' '{print $1}')
service_2=$(ls /etc/systemd/system | grep -e text2 | awk -F ' ' '{print $1}')
service_3=$(ls /etc/systemd/system | grep -e text3 | awk -F ' ' '{print $1}')

Then, I've stopped them in the order i want with checking if the third service is stopped before proceeding with the second one as below,

if [ ! -z "$service_3" ] //if service exists
then
      systemctl start $service_3
else
      :
fi

service_3_status=$(systemctl status $service_3 | grep -e "active")
if [ $service_3_status == "active"]
      if [ ! -z "$service_2" ] //if service exists
      then
            systemctl start $service_2
      else
            :
      fi
else
systemctl start $service_3
fi

service_2_status=$(systemctl status $service_2 | grep -e "active")
if [ $service_2_status == "active"]
      if [ ! -z "$service_1" ] //if service exists
      then
            systemctl start $service_1
      else
            :
      fi
else
systemctl start $service_2
fi

What i want to do is to loop on the services to make sure that the third service is fully started before moving to the second one and so on and if there is a service that is not fully started, It will wait till it's fully started (For example: 4 minutes) but not moving to the next service and if it's still stopped, It will try to stop and start it and if it is still not started it will print out a message with the service name that it cannot be started and this needs an investigation, As per the above code, It will try to start the service if it is not fully started and at the same time it will proceed with the next one which is not the behavior i want, What is the proper way to do this ?

1 Answers

Doing a quick check on systemd's docs, there are options/process to wait/check for the service or if there are unit files, but here is a nested loop that might do what you wanted.

#!/usr/bin/env bash

##: Do your variable service assignment here

for service in "$service_3" "$service_2" "$service_1"; do
  if [[ -n "$service" ]]; then
    systemctl start "$service"
    until systemctl status active "$service" >/dev/null; do
      sleep 10
      systemctl start "$service"
    done
  fi
done

  • Add a sleep after starting the service if needed.

See how-can-a-systemd-service-flag-that-it-is-ready-so-that-other-services-can-wait for more info on howto do it the systemd way.


It looks like init.d all over again though...

Related