我有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
我如何得到这个?
答案 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.sh
和b.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