bash中的障碍,可以轻松完成吗?

Chr*_*dal 6 bash

假设我有一个bash脚本并行执行三个脚本

./script1 &
./script2 &
./script3 &
Run Code Online (Sandbox Code Playgroud)

现在,让我们说./script4依赖于script1,script2和script3.我如何强制它等待那些,同时仍然并行执行三个脚本?

oli*_*bre 8

您可以使用Bash和其他shell中wait提供的内置命令.(请参阅Windows上的等效命令WAITFOR)

wait 文件

等待每个指定的进程完成并返回其终止状态.

Syntax
      wait [n ...]
Key
   n   A process ID or a job specification
Run Code Online (Sandbox Code Playgroud)

每个n都可以是进程ID或作业规范; 如果给出了作业规范,则等待该作业的管道中的所有进程.

如果n未给出,则等待所有当前活动的子进程,并且返回状态为零.

如果n指定不存在的进程或作业,则返回状态为 127.否则,返回状态是最后一个进程或作业等待的退出状态.

简单解决方案

下面wait无限期地等待所有当前活动的子进程全部结束(即在这种情况下是三个脚本).

./script1 &
./script2 &
./script3 &
wait       # waits for all child processes
./script4
Run Code Online (Sandbox Code Playgroud)

将PID存储在shell局部变量中

./script1 & pid1=$!
./script2 & pid2=$!
./script3 & pid3=$!
wait $pid1 $pid2 $pid3  # waits for 3 PIDs
./script4
Run Code Online (Sandbox Code Playgroud)

将PID存储在临时文件中

./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
Run Code Online (Sandbox Code Playgroud)

最后一个解决方案使用三个文件(1.pid,2.pid3.pid)污染当前目录.其中一个文件在wait调用之前可能已损坏.此外,这些文件可能会在崩溃的情况下留在文件系统中.


Ada*_*iss 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.
Run Code Online (Sandbox Code Playgroud)

最简单的实现可能是您的上一个脚本启动其他脚本.这样它就可以很容易地存储它们的PID并将它们传递给它们wait.

  • @CarlNorum:没错,但有时你需要知道你在找什么才能找到它!即使是有经验的程序员也需要偶尔指向正确的文档. (3认同)