0

we have a request to execute multiple shell scripts(scripts that starts application servers) in a sequential manner

The real bet is we have to verify the process(pid) is up or not before proceeding to next script. if no process is running then display an error message and continue with next script

Also send an consolidate email with error (which script got failed) after completion of executing(running) all scripts

Note: These services are not dependent its just that we are checking the the status after each script

Below is what i came up with...please Help

 #!/bin/bash

./script1.sh
PID=`ps -ef | grep c3f | grep -v grep | awk '{print $2}' | wc -l`
if [ $PID -ne 0 ]; then
        echo "error pls check";
 fi

./script2.sh
PID1=`ps -ef | grep d3f | grep -v grep | awk '{print $2}' | wc -l`
if [ $PID1 -ne 0 ]; then
        echo "error pls check";
 fi

./script3.sh
 PID2=`ps -ef | grep E3f | grep -v grep | awk '{print $2}' | wc -l`
if [ $PID2 -ne 0 ]; then
        echo "error pls check";
 fi
RCzone
  • 51
  • 1
  • 7
  • 1
    Use a proper process supervision system -- runit, upstart, systemd, etc; any such system worth its salt will let you define post-start hooks to check if a service is really running correctly, and dependencies so a service isn't started until other services named as dependent are running correctly. Do not start services with shell scripts. – Charles Duffy Sep 06 '18 at 00:03
  • 1
    If you're on a modern Ubuntu or Red Hat distro use [systemd](https://www.freedesktop.org/wiki/Software/systemd/) to start your services. It's a heck of a lot more robust and featureful than any script you could concoct. You really don't want to reinvent this wheel. – John Kugelman Sep 06 '18 at 00:06
  • 1
    When you say, "after completion of executing all scripts," do you mean after they have all been STARTED, of after they have all FINISHED RUNNING? – Jack Sep 06 '18 at 00:26
  • After finishing running @Jack – RCzone Sep 06 '18 at 16:04

3 Answers3

1

You can use $! to get the PID of the last process put into the background. You can add whatever you want inside those if blocks to track which went wrong. The wait command waits for all the background processes to finish. You can print out whatever you want after that for post-processing.

#!/bin/bash

./script1.sh &
ps $! > /dev/null
if [ $? -ne 0 ]; then
    echo "error pls check";
fi

./script2.sh
ps $! > /dev/null
if [ $? -ne 0 ]; then
    echo "error pls check";
fi

./script3.sh
ps $! > /dev/null
if [ $? -ne 0 ]; then
    echo "error pls check";
fi

wait
Jack
  • 5,801
  • 1
  • 15
  • 20
1

You can use pgrep command to find processes by name, for example

to find processes which name includes c3f:

pgrep c3f

to find processes which the full command line includes string c3f

pgrep -f c3f

We can re-write the script, as follow:

#!/bin/bash

declare -a PROCESSES_NOT_FOUND=()

./script1.sh
if ! pgrep -f c3f; then
    PROCESSES_NOT_FOUND+=(c3f)
    echo "Not found c3f, error pls check";
fi

./script2.sh
if ! pgrep -f d3f; then
    PROCESSES_NOT_FOUND+=(d3f)
    echo "Not found d3f, error pls check";
fi

./script3.sh
if ! pgrep -f E3f; then
    PROCESSES_NOT_FOUND+=(E3f)
    echo "Not found E3f, error pls check";
fi

echo "Not found these processes: ${PROCESSES_NOT_FOUND[@]}"

Or we can use an array to store the mapping of processes and scripts

#!/bin/bash

declare -A PROCESS_MAP
PROCESS_MAP[c3f]=./script1.sh
PROCESS_MAP[d3f]=./script2.sh
PROCESS_MAP[E3f]=./script3.sh

declare -a PROCESSES_NOT_FOUND=()

for PROCESS in "${!PROCESS_MAP[@]}"; do
    "${PROCESS_MAP[$PROCESS]}"
    if ! pgrep -f "$PROCESS"; then
        PROCESSES_NOT_FOUND+=("$PROCESS")
        echo "Not found $PROCESS, error pls check";
    fi
done

echo "Not found these processes: ${PROCESSES_NOT_FOUND[@]}"
Feng
  • 3,592
  • 2
  • 15
  • 14
  • Why use all uppercase names for variables? See: [Correct Bash and shell script variable capitalization](https://stackoverflow.com/q/673055/6862601). – codeforester Sep 07 '18 at 18:46
0

This is what i came up with and tested with my requirement

Thanks all for the assistance

testC1.sh

#!/bin/sh

today=`date +%m%d`
err=0

./testCC.sh start s1a cc
PID1=`ps -ef|grep -E 'c35f.*s1a' | grep -v grep | awk '{print $2}'`
if [ "$PID1" -eq 0 ] || [ -z "$PID1" ]; then
        # PROCESS s1a not started
        err=$(( err + 1))
else
        echo "$(date) - Process s1a with $PID1 is running " > /tmp/log_"$today".log
fi

./testCC.sh start s1b cc
PID2=`ps -ef|grep -E 'c35f.*s1b' | grep -v grep | awk '{print $2}'`
if [ "$PID2" -eq 0 ] || [ -z "$PID2" ]; then
        # PROCESS s1b not started
        err=$(( err + 2))
else
        echo "$(date) - Process s1b is running: $PID2 " >> /tmp/log_"$today".log
fi

./testCC.sh start s2a cc
PID3=`ps -ef|grep -E 'c35f.*s2a' | grep -v grep | awk '{print $2}'`
if [ "$PID3" -eq 0 ] || [ -z "$PID3" ]; then
        # PROCESS s2a not started
        err=$(( err + 3))
else
        echo "$(date) - Process s2a with $PID3 is running " > /tmp/log_"$today".log
fi
./testCC.sh start s2b cc
PID4=`ps -ef|grep -E 'c35f.*s2b' | grep -v grep | awk '{print $2}'`
if [ "$PID4" -eq 0 ] || [ -z "$PID4" ]; then
        # PROCESS s2b not started
        err=$(( err + 4))
else
        echo "$(date) - Process s2b is running: $PID4 " >> /tmp/log_"$today".log
fi


if (( $err > 0 )); then
        # identify which PROCESS had the problem.
        if (( $err == 1 )); then
                condition="PROCESS s1a is down"
        elif (( $err == 2 )); then
                condition="PROCESS s1b is down"
        elif (( $err == 3 )); then
                condition="PROCESS s2a is down"
        elif (( $err == 4 )); then
                condition="PROCESS s2b is down"
        else
                condition="Process didnt started properly..Please Check"
        fi

#  send an email to get eyes on the issue

echo "$condition on $(hostname)
on $(date)\n please login to the server to check the process" | mail -s "Alert  Daily Bounce" emailid@corp.com

else

echo "Script on $(hostname) at $(date) sucessfully implemented" | mail -s "Notice  Daily Bounce"  -r 'emailid@corp.com' emailid@corp.com

fi
RCzone
  • 51
  • 1
  • 7