Bash之wait命令

评论 0 浏览 0 2021-01-27

wait是一条等待给定作业完成的命令,并返回被等待的命令的退出状态

由于wait命令会影响到当前的shell执行环境,所以它在大多数shell中都是作为一个内置命令来实现的。

在这篇文章中,我们将探讨Bash内置的wait命令。

Bash wait 命令

wait内置的一般语法有以下形式。

wait [options] ID

ID是进程或工作ID。如果没有指定ID,命令将等待所有的子后台作业完成。

wait命令返回所等待的最后一条命令的退出状态。

例如,要等待一个PID为7654的后台进程,你可以使用。

wait 7654

当给出多个进程时,命令会等待所有的进程完成。

工作是用工作规范("jobspec")来指定的,它是指组成工作的过程的一种方式。Jobspec以一个百分比符号开始,后面是工作编号(%n)。下面是一个例子。

在一个背景中运行一个命令

rsync -a /home /tmp/home &

shell作业ID(用括号包围)和进程ID将显示在你的终端上。

输出

[2] 54377

要等待作业,请运行wait命令,后面跟上作业规范。

wait %2

当用-n选项调用时,该命令只等待给定的pids或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版本,你会得到一个 "无效选项 "的错误。

-f选项告诉wait等待每个pid或jobspec真正终止后再返回其退出代码,而不是在作业状态改变时返回。这个选项只有在作业控制被启用时才有效。默认情况下,作业控制只对交互式提示启用。

实例分析

wait通常用于产生并行执行的子进程的shell脚本中。

为了说明该命令是如何工作的,请创建下面的脚本。

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

让我们逐行解释一下这段代码。

  1. 第一行被称为shebang,它告诉操作系统使用哪一个解释器来解析文件的其余部分。
  2. 我们正在使用sleep命令来模拟一个耗时的后台进程。
  3. $!是一个内部的Bash变量,它存储了在后台运行的最后一个作业的PID。在这个例子中,这就是sleep命令的PID。我们将PID存储在一个变量中(process_id)。
  4. 打印PID号码。
  5. PID被传递给wait命令,而wait命令则等待sleep命令的完成。
  6. 打印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命令将完成并返回进程的退出代码。

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

sleep 3600 &wait -f 46671

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

kill -STOP 46671

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

总结

wait命令等待指定的作业完成,并返回该作业的退出代码。

如果你有任何问题或反馈意见,请随时留言。

最后更新2023-06-28
0 个评论
标签