假设我有一个bash脚本并行执行三个脚本
./script1 &
./script2 &
./script3 &
现在,让我们说./script4依赖于script1,script2和script3。我怎么能强迫它等待那些,同时仍然并行执行这三个脚本?
答案 0 :(得分:8)
您可以在wait
和其他一些shell中使用Bash内置命令。
(请参阅Windows上的等效命令WAITFOR)
wait
documentation 等待每个指定的进程完成并返回其终止 状态。
Syntax wait [n ...] Key n A process ID or a job specification
每个
n
可以是进程ID或作业规范;如果一份工作 给出了规范,该作业的管道中的所有进程都是 等待。如果未给出
n
,则等待所有当前活动的子进程 for,返回状态为零。如果
n
指定不存在的流程或作业,则返回状态为127
。否则,返回状态是最后一个进程或作业等待的退出状态。
低于wait
,无限期等待所有当前活动的子进程全部结束(即在这种情况下是三个脚本)。
./script1 &
./script2 &
./script3 &
wait # waits for all child processes
./script4
./script1 & pid1=$!
./script2 & pid2=$!
./script3 & pid3=$!
wait $pid1 $pid2 $pid3 # waits for 3 PIDs
./script4
./script1 & echo $! >1.pid
./script2 & echo $! >2.pid
./script3 & echo $! >3.pid
wait $(<1.pid) $(<2.pid) $(<3.pid)
rm 1.pid 2.pid 3.pid # clean up
./script4
最后一个解决方案使用三个文件(1.pid
,2.pid
和3.pid
)污染当前目录。在wait
调用之前,其中一个文件可能已损坏。此外,如果发生崩溃,这些文件可能会留在文件系统中。
答案 1 :(得分:6)
来自bash
手册页:
wait [n ...]
Wait for each specified process and return its termination status.
Each `n` may be a process ID or a job specification.... If `n` is not
given, all currently active child processes are waited for, and the return
status is zero.
最简单的实现可能是您的上一个脚本启动其他脚本。这样它就可以很容易地存储它们的PID并将它们传递给wait
。
答案 2 :(得分:1)
# Run each supplied argument as a bash command, inheriting calling environment.
# bash_parallel's can be nested, though escaping quotes can be tricky -- define helper function for such cases.
# Example: bash_parallel "sleep 10" "ls -altrc"
function bash_parallel
{
(
i=0
unset BASH_PARALLEL_PIDS # Do not inherit BASH_PARALLEL_PIDS from parent bash_parallel (if any)
for cmd in "$@"
do
($cmd) & # In subshell, so sibling bash_parallel's wont interfere
BASH_PARALLEL_PIDS[$i]=$!
echo "bash_parallel started PID ${BASH_PARALLEL_PIDS[$i]}: $cmd"
i=$(($i + 1))
done
echo "bash_parallel waiting for PIDs: ${BASH_PARALLEL_PIDS[@]}"
wait ${BASH_PARALLEL_PIDS[@]}
) # In subshell, so ctrl-c will kill still-running children.
}
使用:
eisbaw@leno:~$ time (bash_parallel "sleep 10" "sleep 5")
bash_parallel started PID 30183: sleep 10
bash_parallel started PID 30184: sleep 5
bash_parallel waiting for PIDs: 30183 30184
real 0m10.007s
user 0m0.000s
sys 0m0.004s