0

I have a cluster with multiple linux servers (6) and IBM Websphere Application Server is running on that. These IBM Websphere Application Servers needs to be started up in a specific order, first server1, then server2 etc.

Currently I have a script that will stop and start the IBM Websphere Application Server when I stop or start the linux server itself.

Now I want to build in that script that it will check what day it is, and biased on the hostname it waits until a specific time, for example:

  • server1, needs to check that if it is a Sunday, and hostname is server1 it needs to wait until 2:00 AM then it will execute
  • server2, needs to check that if it is a Sunday, and hostname is server2 it needs to wait until 2:30 AM then it will execute
  • server3, needs to check that if it is a Sunday, and hostname is server3 it needs to wait until 3:00 AM then it will execute

My issue is how do I code that wait until a specific time? If have the following to check about the day and hostname:

DOW=$(date +"%a")
if [ $DOW = "Sun" ] then
if [ $HOSTNAME = server1 ] then
wait until 2:00 AM
and then continue with this
        cat $WAS_TEMP/nodeagent.startup | while read NODE
        do
                echo "Start Nodeagent"
                /opt/ws/profiles/$NODE/bin/startNode.sh > /dev/null &
                sleep 45
        done

if [ $HOSTNAME = server2 ] then
wait until 2:30 AM
and then continue with this
        cat $WAS_TEMP/nodeagent.startup | while read NODE
        do
                echo "Start Nodeagent"
                /opt/ws/profiles/$NODE/bin/startNode.sh > /dev/null &
                sleep 45
        done
if [ $HOSTNAME = server3 ] then
wait until 3:00 AM
and then continue with this
        cat $WAS_TEMP/nodeagent.startup | while read NODE
        do
                echo "Start Nodeagent"
                /opt/ws/profiles/$NODE/bin/startNode.sh > /dev/null &
                sleep 45
        done
fi

It has to be done in the script itself so no crontab.

F. Hauri - Give Up GitHub
  • 64,122
  • 17
  • 116
  • 137
fabje
  • 29
  • 1
  • 7
  • run a google search on `bash wait until a given time` to get several SE/SO hits, eg: [this](https://stackoverflow.com/q/645992), [this](https://stackoverflow.com/q/17548064) and [this](https://unix.stackexchange.com/q/94518); another option that may work is the `at` command; general question ... what happens if your script is run @ 07:30? I'm assuming you don't really want to wait until 02:xx **tomorrow** ... – markp-fuso Oct 16 '20 at 17:30
  • You might want to pick up something like [tag:ansible] or [tag:chef]. – SiKing Oct 16 '20 at 18:29
  • @markp-fuso the script runs only on a sunday, when on the linux machines are getting there new linux updates installed. This update is automatically done at 1 am on a sunday. So at 2 am the system is back up with the new installed updates, so thats why at 2 am the script can run. The main script that I'm talking about is being started using a systemctl service. ExecStart=/opt/scripts/websphere.sh start – fabje Oct 16 '20 at 21:18
  • There is already an answer: [Sleep until a specific time/date](https://stackoverflow.com/q/645992/1765658) – F. Hauri - Give Up GitHub Oct 20 '20 at 15:32

1 Answers1

1

From your example code, it seems all servers need to execute the same code. So, the following script should work for your usecase:

#!/bin/bash

declare -A myservertime
myservertime["server1.example.com.bd"]="02:00"
myservertime["server2.example.com.bd"]="02:30"
myservertime["server3.example.com.bd"]="03:00"
myservertime["server4.example.com.bd"]="03:30"

for keys in "${!myservertime[@]}";
    do
        if [[ "$keys" == "$HOSTNAME" ]]; then
            mylaunchtime=${myservertime["$keys"]}
        fi
    done
if [ -z "$mylaunchtime" ]; then
    echo "Server not found."
    exit
fi

timenow=$(date +"%s")
weekday=$(date +"%a" -d @$timenow )
timerun=$(date +"%s" -d ${mylaunchtime} )
if [ $timerun -lt $timenow ]; then
    timerun=$(( timerun + 86400 ))
fi
sleep_time=$(( timerun - timenow ))

if [ $weekday == "Sat" ]; then
    sleep $sleep_time
    cat $WAS_TEMP/nodeagent.startup | while read NODE
    do
            echo "Start Nodeagent"
            /opt/ws/profiles/$NODE/bin/startNode.sh > /dev/null &
            sleep 45
    done
fi

If you don't need to search the $HOSTNAME from within the script, then you could use a simpler script like below, and launch it with a command line argument like ./mysript.sh 2 for launching the 3rd (out of 4) servers:

#!/bin/bash

mylaunchtime=("02:00" "02:30" "03:00" "03:30")

timenow=$(date +"%s")
weekday=$(date +"%a" -d @$timenow )
timerun=$(date +"%s" -d ${mylaunchtime[$1]} )
if [ $timerun -lt $timenow ]; then
    timerun=$(( timerun + 86400 ))
fi
sleep_time=$(( timerun - timenow ))

if [ $weekday == "Sun" ]; then
    sleep $sleep_time
    cat $WAS_TEMP/nodeagent.startup | while read NODE
    do
            echo "Start Nodeagent"
            /opt/ws/profiles/$NODE/bin/startNode.sh > /dev/null &
            sleep 45
    done
fi
Nyamul
  • 76
  • 4
  • Indeed the script is being used at all 6 servers, only the script is being started using a systemctl service: ```ExecStart=/opt/scripts/websphere.sh start``` The code looks good and thank you for that. Only I had the idea to include the hostnames of all the servers in the script aswell, so I don't have to change the ExecStart in the systemctl. Only how should that code would look like including the hostname part? – fabje Oct 16 '20 at 21:24
  • Maybe something like this, replace ```mylaunchtime=("02:00" "02:30" "03:00" "03:30")``` For this: ```server1 = "02:00" server2 = "02:30" server3 = "03:00" mylaunchtime=($server1 $server2 $server3)``` I'm only missing a check to see on what server it is running so it will know if it is server1 ,2 or 3? I never get line breaks to work here, so the layout is crap sorry for that. – fabje Oct 16 '20 at 21:41
  • Updated with the in-script `$HOSTNAME` check. – Nyamul Oct 17 '20 at 10:08