3

バックグラウンドで実行される 3 つのプロセス a.sh、b.sh、c.sh があります。

./a.sh &
pid_a=$!

./b.sh &
pid_b=$!

./c.sh &
pid_c=$!

最長のプロセスが終了するまで、3 つのプロセスすべてが実行されるようにする必要があります。個々の実行時間で 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

一時ファイルをフラグとして使用して、各プロセスが初めて完了したときを示すことができます。他の 2 つのスクリプトがそれぞれ少なくとも 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.shwait

次に、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 つのバックグラウンド ジョブとして生成し、単純なジョブと 2 つのモニターwaitを待機さc.shせます。

注:が実行中か終了したかをkill -0 $PID返します。0$PID1$PID

于 2012-08-09T11:48:40.650 に答える
0

[これは bash でのみ機能します。ksh93 killの動作は異なります。]

強制終了できるプロセスが少なくとも 1 つある限り、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

Builtinkillはエラーに関して一貫していません:

$ 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 に答える