Bash之wait命令
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: $?"
让我们逐行解释一下这段代码。
- 第一行被称为shebang,它告诉操作系统使用哪一个解释器来解析文件的其余部分。
- 我们正在使用
sleep
命令来模拟一个耗时的后台进程。 $!
是一个内部的Bash变量,它存储了在后台运行的最后一个作业的PID。在这个例子中,这就是sleep
命令的PID。我们将PID存储在一个变量中(process_id
)。- 打印PID号码。
- PID被传递给
wait
命令,而wait
命令则等待sleep
命令的完成。 - 打印
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
命令等待指定的作业完成,并返回该作业的退出代码。
如果你有任何问题或反馈意见,请随时留言。