Bash:后台作业完成时执行

Bash:后台作业完成时执行

如果你想连续运行一系列命令,你可以执行

command1 & command2 & command3 &

如果我执行command1,然后Ctrl+ Z,然后bg,它将command1在后台运行。

我的问题是,如果我执行command1并将其发送到后台,是否可以告诉 bash 等待它完成,然后command2command3它终止后在后台执行?

答案1

该命令wait,无需进一步说明,将要等待结束所有活动的子进程。这意味着如果还有另一个进程,它将等待最后一个进程结束。

可以指定 ID 来调用 Wait: 有身份证可以通行,或者PID(进程 ID)或工作规范。此外,如果它不是一个单个命令而是一个管道,wait则会等待整个管道的结束(见下文)。

因此wait 7165它将等待 ID 为 7165 的进程结束,并wait %2执行该作业[2]

在脚本中,您可以使用变量存储最后发送的作业的 PID $!;您需要存储该值,因为它将在每次执行命令后更新。

#!/bin/bash
...
command1 &                             # Another command in background  job [1]
command2 && command2b && command2c &   # The command in background      job [2]
PID_CMD1=$!                            # Store the PID of the last job, job [2]

some_other_commands       # ...       

                          # With this command you will 
wait                      # block all until command0 and all  
                          # the pipe of command1 are completed or...

wait $PID_CMD1            # With this command you will wait only the end
                          # of command1 pipeline or...

wait %2                   # With this command you'll wait the end of job [2]    
                          # Note that if the command 1 fails or is really fast 
                          # you can have for the command 2 the job ID 1
command3 &                # job [1] again! it's possible to recycle the numbers
command4 &                # job [2] 

man bash

该外壳关联一个工作每个管道都有。它保存当前正在执行的作业的表,可以使用 jobs 命令列出。当 bash 异步启动作业(在后台)时,它会打印一行,如下所示:
[1] 25647
表示此作业的作业编号为 1,并且与此作业关联的管道中的最后一个进程的进程 ID 为 25647。单个管道中的所有进程都是同一作业的成员。Bash 使用作业抽象作为作业控制的基础...

您可以阅读有关等待的更多信息help wait

答案2

假设您想在启动后command1但在等待它完成之前执行其他操作,请使用 shell 内置命令wait

command1 &
some_other_command
wait  # block until command1 completes

command2 &
command3 &

相关内容