Bash wait 命令及其示例

Bash 中的 wait 命令是管理 shell 脚本进程的强大工具。它主要用于暂停脚本的执行,直到指定的后台进程完成。此命令在启动多个后台作业并需要同步其完成才能继续执行其他任务的脚本中非常方便。wait 命令可以应用于单个进程 ID (PID),也可以等待当前 shell 会话启动的所有后台进程。通过使用 wait,您可以确保脚本仅在特定任务完全完成后才向前移动,从而使您的自动化流程更加可靠和高效。

本指南将提供在各种场景中使用 wait 命令的实际示例,帮助您了解如何有效地管理 Bash 脚本中的后台进程。

理解 Bash wait 命令

Bash 中的 wait 命令是一个内置函数,它会暂停当前 shell 的执行,直到指定的作业完成。然后,它会返回其正在等待的命令的退出状态。此命令在 shell 执行环境中起着至关重要的作用,因此,它内置于大多数 shell 中。

wait命令的一般语法如下:

wait [ID]

在此上下文中,ID 表示进程或作业 ID。如果未指定 ID,wait 命令将暂停,直到所有子后台作业都完成。wait 命令返回它等待的最后一个命令的退出状态。

例如,要暂停 PID 为 7654 的后台进程,您可以使用:

wait 7654

如果指定了多个进程,wait命令将暂停,直到它们完成。

使用 bash wait 命令浏览作业规范

作业使用作业规范 (jobspec) 来指定,它指的是组成作业的流程。jobspec 以百分比符号开头,后跟作业编号 (%n)。以下是示例:

rsync -a /home /tmp/home &

此命令在后台运行。shell 作业 ID(括在括号中)和进程 ID 将显示在您的终端上。要暂停作业,请运行 wait 命令,然后运行作业规范:

wait %2

使用 bash wait 命令的 -n 选项

-n 选项允许 wait 命令仅暂停以等待给定 PID 或 jobspecs 中的单个作业完成并返回其退出状态。如果没有提供参数,wait -n 将等待任何后台作业完成并返回作业退出状态。

wait -n 45432 54346 76573

在上面的例子中,wait -n 仅打印第一个退出的作业的返回状态;它不显示作业的 PID。如果你想获取返回退出状态的作业 PID 或 jobspec,请使用 -p 将其分配给变量的选项:

wait -p job_id -n 45432 54346 76573

-p 选项是在 Bash 5.1 中引入的。使用旧版本的 Bash 将导致“无效选项”错误。

使用 bash wait 命令探索 -f 选项

-f 选项指示等待每个 PID 或 jobspec 终止后再返回其退出代码,而不是在作业状态更改时返回。此选项仅在启用作业控制时有效,默认情况下仅在交互式提示中启用。

wait 命令的实例

wait 命令通常用于生成并行执行的子进程的 shell 脚本中。为了说明该命令的工作原理,让我们创建以下脚本:

#!/bin/bash
sleep 30 &
process_id=$!
echo "PID: $process_id"
wait $process_id
echo "Exit status: $?"

让我们逐行分解代码:

  • 第一行,shebang,告诉操作系统使用哪个解释器来解析文件的其余部分。
  • 我们正在使用 sleep 命令来模拟耗时的后台进程。
  • $! 是一个内部 Bash 变量,用于存储后台运行的最后一个作业的 PID。在此示例中,它是 sleep 命令的 PID。我们将 PID 存储在变量 (process_id) 中。
  • 打印 PID 编号。
  • PID 被传递给等待命令,该命令会暂停直到睡眠命令完成。
  • 打印 wait 命令的退出状态。$? 是一个内部 Bash 变量,用于保存最后执行的命令的退出状态。

如果你运行该脚本,它将打印如下内容:

PID: 36353
Exit status: 0

以下是使用 -n 选项的示例:

#!/bin/bash
sleep 3 &
sleep 30 &
sleep 5 &
wait -n
echo "First job completed."
wait
echo "All jobs completed."

当执行脚本时,它会生成 3 个后台进程。wait -n 暂停直到第一个作业完成并打印 echo 语句。wait 暂停直到所有子后台作业完成。

First job completed.
All jobs completed.

最后一个例子解释了 -f 选项。打开终端并运行:

sleep 3600 &
[1] 46671
wait 46671

打开另一个终端并使用 kill 命令停止该进程:

kill -STOP 46671

一旦进程状态发生改变,等待命令就会完成,并返回进程退出代码。

现在,重复相同的步骤,但这次使用 wait -f $pid:

sleep 3600 &
wait -f 46671

从另一个终端停止该进程:

kill -STOP 46671

这次,wait命令不会完成。它将一直运行,直到睡眠过程终止。

wait 命令的高级用法

wait 命令在管理脚本中的多个进程时特别有用。它允许您控制执行流程并确保特定进程在其他进程开始之前完成。让我们深入研究一些更复杂的示例来说明这一点。

Bash 等待多个进程

考虑这样一种情况:多个进程在后台运行,您必须在完成这些进程后才采取行动。以下是使用 wait 命令实现此目的的方法:

#!/bin/bash
echo "Starting process 1..."
sleep 10 &
pid1=$!

echo "Starting process 2..."
sleep 15 &
pid2=$!

echo "Starting process 3..."
sleep 20 &
pid3=$!

echo "Waiting for processes to complete..."
wait $pid1 $pid2 $pid3
echo "All processes completed."

此脚本启动三个后台进程,它们分别休眠 10、15 和 20 秒。我们将每个进程的 PID 存储在一个变量中。然后,我们使用 wait 命令并将所有三个 PID 作为参数。脚本将在 wait 命令处暂停,直到所有三个进程都已完成。

使用 Bash 循环等待

您还可以使用循环来管理多个进程。以下是示例:

#!/bin/bash
for i in {1..5}
do
   echo "Starting process $i..."
   sleep $i &
   pids[${i}]=$!
done

echo "Waiting for processes to complete..."
for pid in ${pids[*]}; do
    wait $pid
done

echo "All processes completed."

在此脚本中,我们在一个循环内启动了五个后台进程。每个进程的休眠时间等于其在循环中的索引。我们将每个进程的 PID 存储在一个数组中。启动所有进程后,我们循环遍历该数组并使用 wait 命令分别暂停每个进程。脚本将在每个 wait 命令处暂停,直到相应的进程完成。

结论

Bash 中的 wait 命令对于同步脚本中的后台进程至关重要。通过了解如何使用 wait,您可以更精确地控制脚本的流程,确保任务按所需的顺序完成。无论您是处理多个后台作业还是必须确保特定进程在继续之前完成,wait 命令都可以帮助您实现更可靠和可预测的脚本行为。考虑将 wait 集成到脚本中以增强进程管理并提高整体脚本效率。

Joshua James
跟我来
Joshua James 的最新帖子 (查看全部)

发表评论