3

我有 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

我怎么得到这个?

4

3 回答 3

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"
于 2012-08-09T14:02:21.117 回答
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将与 2 个监视器一样等待c.sh

注意:如果正在运行或已终止,则kill -0 $PID返回。0$PID1$PID

于 2012-08-09T11:48:40.650 回答
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
于 2012-08-09T12:51:59.367 回答