Search code examples
linuxbashshell

Check running status of a background process launched from same bash script


I have to write a bash script that launches a process in background in accordance to command line argument passed and returns if it were successfully able to run launch the program.

Here is a pseudo code of what I am trying to achieve

if [ "$1" = "PROG_1" ] ; then
    ./launchProg1 &
    if [ isLaunchSuccess ] ; then
        echo "Success"
    else
        echo "failed"
        exit 1
    fi
elif [ "$1" = "PROG_2" ] ; then
    ./launchProg2 &
    if [ isLaunchSuccess ] ; then
        echo "Success"
    else
        echo "failed"
        exit 1
    fi
fi

Script cannot wait or sleep since it will be called by another mission critical c++ program and needs high throughput ( wrt no of processes started per second ) and moreover running time of processes are unknown. Script neither needs to capture any input/output nor waits for launched process' completion.

I have unsuccessfully tried the following:

#Method 1
if [ "$1" = "KP1" ] ; then
    echo "The Arguement is KP1"
    ./kp 'this is text' &
    if [ $? = "0" ] ; then
        echo "Success"
    else
        echo "failed"
        exit 1
    fi
elif [ "$1" = "KP2" ] ; then
    echo "The Arguement is KP2"
    ./NoSuchCommand 'this is text' &
    if [ $? = "0" ] ; then
        echo "Success"
    else
        echo "failed"
        exit 1
    fi
#Method 2
elif [ "$1" = "CD5" ] ; then
    echo "The Arguement is CD5"
    cd "doesNotExist" &
    PROC_ID=$!
    echo "PID is $PROC_ID"
    if kill -0 "$PROC_ID" ; then
        echo "Success"
    else
        echo "failed"
        exit 1
    fi
#Method 3
elif [ "$1" = "CD6" ] ; then
    echo "The Arguement is CD6"
    cd .. &
    PROC_ID=$!
    echo "PID is $PROC_ID"
    ps -eo pid | grep "$PROC_ID" && { echo "Success"; exit 0; }
    ps -eo pid | grep  "$PROC_ID" || { echo "failed" ; exit 1; }
else
    echo "Unknown Argument"
    exit 1
fi

Running the script gives unreliable output. Method 1, 2 always return Success while Method 3 returns failed when process execution finishes before the checks.

Here is sample tested on GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu) and GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)

[scripts]$ ./processStarted3.sh KP1
The Arguement is KP1
Success
[scripts]$ ./processStarted3.sh KP2
The Arguement is KP2
Success
./processStarted3.sh: line 13: ./NoSuchCommand: No such file or directory
[scripts]$ ./processStarted3.sh CD6
The Arguement is CD6
PID is 25050
failed

As suggested in similar questions, I cannot use process names as one process may be executed several times and others can't be applied.

I have not tried screen and tmux, since getting permission to install them on production servers wont be easy ( but will do so if that is the only option left )

UPDATE
@ghoti
./kp is program which exists and launching the program returns Success. ./NoSuchCommand does not exist. Still as you can see from (edited) output, script incorrectly returns Success.

It does not matter when the process completes execution or program abnormally terminates. Programs launched via script are not tracked in any way ( hence we do not store pid in any table nor necessity arises to use deamontools ).

@Etan Reisner
Example of a program which fails to launch will be ./NoSuchCommand,which does not exist. Or maybe a corrupted program which fails to start.

@Vorsprung
Calling a script which launches a program in background does not take alot of time ( and is manageable as per our expectations). But sleep 1 will accumulate over time to cause issues.

Aforementioned #Method3 works fine barring processes which terminate before ps -eo pid | grep "$PROC_ID" && { echo "Success"; exit 0; } check can be performed.


Solution

  • Here is an example which will show the result of a process whether it is started successfully or not.

    #!/bin/bash
    $1 & #executes a program in background which is provided as an argument
    pid=$! #stores executed process id in pid
    count=$(ps -A| grep $pid |wc -l) #check whether process is still running
    if [[ $count -eq 0 ]] #if process is already terminated, then there can be two cases, the process executed and stop successfully or it is terminated abnormally
    then
            if wait $pid; then #checks if process executed successfully or not
                    echo "success"
            else                    #process terminated abnormally
                    echo "failed (returned $?)"
            fi
    else
            echo "success"  #process is still running
    fi
    
    #Note: The above script will only provide a result whether process started successfully or not. If porcess starts successfully and later it terminates abnormally then this sciptwill not provide a correct result