如何在此方案中继续执行后台进程

时间:2012-08-09 09:56:52

标签: bash unix background-process

我有3个处理a.sh,b.sh,c.sh,它们是在后台执行的。

./a.sh &
pid_a=$!

./b.sh &
pid_b=$!

./c.sh &
pid_c=$!

我需要确保所有三个进程一直运行,直到最长的进程终止。如果c.sh需要10秒,a.sh需要3秒,b.sh需要5秒才能执行单独的执行时间,我需要再次执行a.sh,b.sh以确保它们存在直到c.sh完成。

我正在尝试这种方法,这在上述场景中肯定不起作用

 ./a.sh &
 while ps -p $! > /dev/null; do

./b.sh &
 pid_b=$!

./c.sh &
pid_c=$!

wait $pid_c
done

我如何得到这个?

3 个答案:

答案 0 :(得分:1)

您可以将临时文件用作标志,以指示每个进程第一次完成的时间。在后台循环中运行每个脚本,直到其他两个脚本中的每个脚本至少完成一次。

flag_dir=$(mktemp -d flagsXXXXX)
flag_a=$flag_dir/a
flag_b=$flag_dir/b
flag_c=$flag_dir/c

( until [[ -f $flag_b && -f $flag_c ]]; do ./a.sh; touch $flag_a; done; ) &
( until [[ -f $flag_a && -f $flag_c ]]; do ./b.sh; touch $flag_b; done; ) &
( until [[ -f $flag_a && -f $flag_b ]]; do ./c.sh; touch $flag_c; done; ) &

# Each until-loop runs until it sees the other two have completed at least one
# cycle. Wait here until each loop finishes.
wait

# Clean up
rm -rf "$flag_dir"

答案 1 :(得分:0)

首先,您可以使用kill -0来测试c.sh的流程状态,而不是使用wait等待它终止。

其次,您可以使用2个单独的流程来监控脚本a.shb.sh

的状态

第三,这假设c.sh是运行时间最长的过程。

因此,监控流程1执行以下操作:

# I have pid_c
./a.sh &
pid_a=$!
while wait $pid_a; do
    if kill -0 $pid_c; then
        ./a.sh&
        pid_a=$!
    fi
done

并且监控进程2执行以下操作:

# I have pid_c
./b.sh &
pid_b=$!
while wait $pid_b; do
    if kill -0 $pid_c; then
        ./b.sh &
        pid_b=$!
    fi
done

因此,您将分别监控2个流程。但是,如果您还需要监视它们,那么将监视器生成为2个后台作业,一个简单的wait将等待c.sh以及2个监视器。

注意:如果kill -0 $PID正在运行,则0会返回$PID;如果1已终止,则会$PID

答案 2 :(得分:0)

[注意这仅适用于bash。 ksh93 kill表现不同。]

只要至少有一个进程被允许杀死,kill -0将返回成功。根据需要调整间隔。

#! /bin/bash
interval=1
pids= && for t in 2 3; do
    (sleep $t && echo slept $t seconds) & pids=${pids:+$pids }$!
done

while (kill -0 $pids) 2>& -; do
    sleep $interval
    # optional reporting:
    for pid in $pids; do
        (kill -0 $pid) 2>&- && echo $pid is alive
    done
done

结果:

6463 is alive
6464 is alive
slept 2 seconds
[1]-  Done                    eval sleeper $t
6464 is alive
slept 3 seconds
[2]+  Done                    eval sleeper $t

内置kill在错误方面不一致:

$ ksh -c 'kill -0 571 6133 && echo ok || echo no'
kill: 571: permission denied
no
$ bash -c 'kill -0 571 6133 && echo ok || echo no'
bash: line 0: kill: (571) - Operation not permitted
ok