在bash脚本中检查和终止挂起的后台进程

在bash脚本中检查和终止挂起的后台进程,bash,process,wait,kill,pid,Bash,Process,Wait,Kill,Pid,假设我在bash中有这个伪代码 #!/bin/bash things for i in {1..3} do nohup someScript[i] & done wait for i in {4..6} do nohup someScript[i] & done wait otherThings 说这话的时候,我有时会被绞死 有没有办法获取进程ID(使用$!) 并定期检查进程是否花费了超过指定时间量的时间,之后我想使用kill-9终止挂起的进程?

假设我在bash中有这个伪代码

#!/bin/bash

things    
for i in {1..3}
do
    nohup someScript[i] &

done
wait

for i in {4..6}
do
    nohup someScript[i] &

done
wait
otherThings
说这话的时候,我有时会被绞死

有没有办法获取进程ID(使用$!) 并定期检查进程是否花费了超过指定时间量的时间,之后我想使用kill-9终止挂起的进程?

一种可能的方法:

#!/bin/bash

# things
mypids=()
for i in {1..3}; do
    # launch the script with timeout (3600s)
    timeout 3600 nohup someScript[i] &
    mypids[i]=$! # store the PID
done

wait "${mypids[@]}"

不幸的是,@Eugeniu的回答对我不起作用,超时给出了一个错误

然而,我发现做这个程序很有用,我会把它贴在这里,这样任何人都可以利用它,如果我遇到同样的问题。 创建另一个脚本,如下所示

#!/bin/bash
#monitor.sh

pid=$1

counter=10
while ps -p $pid > /dev/null
do
    if [[ $counter -eq 0 ]] ; then
            kill -9 $pid
    #if it's still there then kill it
    fi
    counter=$((counter-1))
    sleep 1
done
然后在你刚才的主要工作中

things    
for i in {1..3}
do
    nohup someScript[i] &
    ./monitor.sh $! &
done
wait

通过这种方式,对于任何someScript,您都将拥有一个并行进程,该进程将在每个选定的间隔(直到计数器决定的最长时间)检查它是否仍然存在,并且如果相关进程死亡(或被杀死),该进程将实际退出。

我实际上需要该“等待”命令以避免填满服务器容量。每个进程占用8个处理器中的一个,这就是为什么我要等待3个进程结束,然后再启动其他进程。这样,您将如何集成wait命令?很抱歉,我现在看到wait命令位于错误的位置。@MarcoPietrosanto首先检查第一个进程中的所有PID,然后在它们全部结束/终止时继续脚本。@MarcoPietrosanto:
wait
将简单地阻止脚本的执行,直到所有进程完成。因此,您需要先睡眠一定时间,然后检查是否有任何进程仍处于活动状态,然后杀死这些活动进程,然后继续。它们通常在几分钟后结束(变量),然后以适当的方式等待捕获。我不需要在“不管发生什么”之前睡固定的时间。我需要这样的东西:-如果进程按其必须的方式运行,只需在不等待固定时间的情况下继续运行-如果进程挂起(超过一个小时或类似的时间),那么它就会杀死它。@Marco Pietrosanto:检查更新的答案。也可以从发布的答案中得到启发。你可以为你启动的每个流程创建一个看门狗。要实现看门狗进程,您可以使用
time-o run.${!}.time nohup someScript[i]
运行主进程,并在启动主进程后将其作为后台进程运行。看门狗应评估
time
命令存储的统计数据。另一种可能更简单的方法是在数组中启动脚本进程时存储时间戳,并在wait命令之前检查后台进程数组和bacground进程中(当前)时间戳数组的每个映射,在
monitor.sh
中,您允许使用
nohup
启动的每个作业的超时时间为10秒?您可以控制它,每个进程允许的最长时间为*而进程每秒钟检查一次。我不明白
monitor.sh
中的while循环与这3个命令之间的区别:
pid=$1;睡觉kill-9$pid
不确定我是否理解您的疑问,但我会尽量澄清:while条件ps-p$pid仅在进程处于活动状态时才为真。因此,每当进程自行结束时,这种情况就不再存在,monitor.sh也将结束。如果进程挂起,while循环将持续到*秒,此时计数器达到0,并且进程被监视器终止(由于while条件现在为false,因此退出监视器本身)