检查从同一 bash 脚本启动的后台进程的运行状态

par*_*thy 5 linux bash shell

我必须编写一个 bash 脚本,根据传递的命令行参数在后台启动一个进程,如果它能够成功运行启动程序,则返回。

这是我想要实现的伪代码

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
Run Code Online (Sandbox Code Playgroud)

脚本不能waitsleep因为它将被另一个关键任务 C++ 程序调用并且需要高吞吐量(每秒启动的进程数),而且进程的运行时间是未知的。脚本既不需要捕获任何输入/输出,也不需要等待启动的进程完成。

我尝试了以下方法失败:

#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
Run Code Online (Sandbox Code Playgroud)

运行脚本会给出不可靠的输出。方法 1、2 总是返回,Success而方法 3failed在检查之前进程执行完成时返回。

这是在GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)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
Run Code Online (Sandbox Code Playgroud)

正如在类似问题中所建议的那样,我不能使用进程名称,因为一个进程可能会执行多次其他进程无法应用。

我没有尝试过screentmux,因为获得在生产服务器上安装它们的许可并不容易(但如果这是唯一的选择,我会这样做)

UPDATE
@goti
./kp是存在的程序并且启动该程序返回Success./NoSuchCommand不存在。正如您从(编辑的)输出中看到的那样,脚本错误地返回Success.

进程何时完成执行或程序异常终止都没有关系。不会以任何方式跟踪通过脚本启动的程序(因此我们不存储pid在任何表中,也没有必要使用deamontools)。

@Etan Reisner
无法启动的程序示例将是./NoSuchCommand不存在的。或者可能是无法启动的损坏程序。

@Vorsprung
调用在后台启动程序的脚本不会花费很多时间(并且可以按照我们的期望进行管理)。但sleep 1随着时间的推移会积累导致问题。

上述#Method3工作很好,ps -eo pid | grep "$PROC_ID" && { echo "Success"; exit 0; }可以执行检查之前终止的进程。

raj*_*dit 4

这是一个示例,它将显示进程是否成功启动的结果。

#!/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
Run Code Online (Sandbox Code Playgroud)