异步任务

Bash脚本有时候需要同时执行多个任务。通常这涉及到启动一个脚本,依次,启动一个或多个子脚本来执行额外的任务,而父脚本继续运行。然而,当一系列脚本 以这种方式运行时,要保持父子脚本之间协调工作,会有一些问题。也就是说,若父脚本或子脚本依赖于另一方,并且 一个脚本必须等待另一个脚本结束任务之后,才能完成它自己的任务,这应该怎么办?

bash 有一个内置命令,能帮助管理诸如此类的异步执行的任务。wait 命令导致一个父脚本暂停运行,直到一个 特定的进程(例如,子脚本)运行结束。

首先我们将演示一下 wait 命令的用法。为此,我们需要两个脚本,一个父脚本:

  1. #!/bin/bash
  2. # async-parent : Asynchronous execution demo (parent)
  3. echo "Parent: starting..."
  4. echo "Parent: launching child script..."
  5. async-child &
  6. pid=$!
  7. echo "Parent: child (PID= $pid) launched."
  8. echo "Parent: continuing..."
  9. sleep 2
  10. echo "Parent: pausing to wait for child to finish..."
  11. wait $pid
  12. echo "Parent: child is finished. Continuing..."
  13. echo "Parent: parent is done. Exiting."

和一个子脚本:

  1. #!/bin/bash
  2. # async-child : Asynchronous execution demo (child)
  3. echo "Child: child is running..."
  4. sleep 5
  5. echo "Child: child is done. Exiting."

在这个例子中,我们看到该子脚本是非常简单的。真正的操作通过父脚本完成。在父脚本中,子脚本被启动, 并被放置到后台运行。子脚本的进程 ID 记录在 pid 变量中,这个变量的值是 $! shell 参数的值,它总是 包含放到后台执行的最后一个任务的进程 ID 号。

父脚本继续,然后执行一个以子进程 PID 为参数的 wait 命令。这就导致父脚本暂停运行,直到子脚本退出, 意味着父脚本结束。

当执行后,父子脚本产生如下输出:

  1. $ async-parent
  2. Parent: starting...
  3. Parent: launching child script...
  4. Parent: child (PID= 6741) launched.
  5. Parent: continuing...
  6. Child: child is running...
  7. Parent: pausing to wait for child to finish...
  8. Child: child is done. Exiting.
  9. Parent: child is finished. Continuing...
  10. Parent: parent is done. Exiting.