wait是一个shell命令,它等待特定进程完成,然后返回其退出状态。wait命令用于等待特定的进程ID和作业ID,并返回其终止状态。
在执行大型自动化流程时,我们需要使几个模块等待到上一组模块完成并返回流水线进入下一个模块的数据,在这种情况下,我们可以使用wait命令直到完成上一个模块。
wait命令如何工作
wait命令用于监视先前的进程,它将返回退出状态。例如,如果我们要等待完成特定的进程ID 13245,则当进程13245完成wait命令返回13245退出状态的返回值时,应使用wait 13245
。
- wait PID(PID-实用程序要等待终止的命令的进程ID)。
- wait JID(JID-标识要等待的后台进程的作业ID,仅适用于当前Shell执行环境中的wait调用)。
等待命令的退出状态值取决于指定的最后一个PID/JID。当任何进程异常终止时,退出状态将大于128。
当它没有子进程调用并且当前shell知道的所有进程ID都已终止时,wait命令将以值0退出。如果wait命令检测到任何错误,那么它将返回1到126之间的任何值。如果最后一个进程ID是未知的,则wait命令将以值127退出。
wait命令示例
让我们使用一些脚本以了解wait命令的工作方式。
示例:1 – 带有wait命令的脚本
我们有两个脚本,分别称为“foo.sh”和“bar.sh”脚本。“Foo.sh”脚本的打印数字介于1到5之间,而“bar.sh”脚本将调用foo.sh并在后台运行它,获取foo.sh的PID并等待其完成,一旦完成,它将启动“bar.sh”循环并完成。
脚本 – foo.sh
#!/bin/bash for i in 1 2 3 4 5 do echo "foo.sh – Looping … number $i" done
脚本 – bar.sh
#!/bin/bash echo "Started bar.sh" echo "Started foo.sh" ./foo.sh & pid=$! wait $pid echo "Completed foo.sh" for I in 1 2 3 4 5 do echo "bar.sh – Looping … number $i" done
结果
Started bar.sh Started foo.sh foo.sh – Looping .. number 1 foo.sh – Looping .. number 2 foo.sh – Looping .. number 3 foo.sh – Looping .. number 4 foo.sh – Looping .. number 5 Completed foo.sh bar.sh – Looping .. number 1 bar.sh – Looping .. number 2 bar.sh – Looping .. number 3 bar.sh – Looping .. number 4 bar.sh – Looping .. number 5 Completed bar.sh $
示例:2 – 没有wait命令的脚本
我们有两个脚本,分别称为“foo.sh”和“bar.sh”脚本。“foo.sh”脚本输出的数字介于1到5之间,而“bar.sh”脚本将调用“foo.sh”并在后台运行它,但它不会等待“foo.sh”完成并执行这两个脚本。
脚本 – foo.sh
#!/bin/bash for i in 1 2 3 4 5 do echo "foo.sh – Looping … number $i" done
脚本 – bar.sh
#!/bin/bash echo "Started bar.sh" echo "Started foo.sh" ./foo.sh & echo "Completed foo.sh" for I in 1 2 3 4 5 do echo "bar.sh – Looping … number $i" done
结果
Started bar.sh Started foo.sh Completed foo.sh bar.sh – Looping .. number 1 bar.sh – Looping .. number 2 bar.sh – Looping .. number 3 bar.sh – Looping .. number 4 bar.sh – Looping .. number 5 Completed bar.sh $ foo.sh – Looping .. number 1 foo.sh – Looping .. number 2 foo.sh – Looping .. number 3 foo.sh – Looping .. number 4 foo.sh – Looping .. number 5 $
示例:3 – 具有wait命令和返回状态的脚本
“bar.sh”脚本将调用foo.sh并在后台运行它,获取foo.sh的PID并等待其完成,一旦完成,它将启动bar.sh循环并完成,最后,它返回foo.sh脚本的退出代码。
脚本 – foo.sh(退出状态= 0)
脚本 - foo.sh
#!/bin/bash for i in 1 2 3 4 5 do echo "foo.sh – Looping … number $i" done
脚本 - bar.sh
#!/bin/bash ./foo.sh & BPID=$! wait $BPID stat=$? if [ $stat –eq 0 ] then echo "Exit status - $stat" else echo "Exit status - $stat" fi
结果
foo.sh – Looping .. number 1 foo.sh – Looping .. number 2 foo.sh – Looping .. number 3 foo.sh – Looping .. number 4 foo.sh – Looping .. number 5 Exit status - 0 $
脚本 – foo.sh (退出状态 = 非0)
脚本 - foo.sh
#!/bin/bash for i in 1 2 3 4 5 do iiecho "foo.sh – Looping … number $i" done
脚本 – bar.sh
#!/bin/bash ./foo.sh & BPID=$! wait $BPID stat=$? if [ $stat –eq 0 ] then echo "Exit status - $stat" else echo "Exit status - $stat" fi
结果
./foo.sh: line 4: iiecho: command not found ./foo.sh: line 4: iiecho: command not found ./foo.sh: line 4: iiecho: command not found ./foo.sh: line 4: iiecho: command not found ./foo.sh: line 4: iiecho: command not found Exit status – 127 $
结论
wait(等待)和sleep(休眠)都是操作系统中基于时间的系统调用。让我们看看wait和sleep命令之间的区别。
- wait(等待):当用户想要停止当前进程并释放该进程持有的所有资源并等待其他进程执行时。我们需要使用notify来使该过程知道在其他过程完成后再次开始执行。
notify通知链机制是Linux内核级别的模块间通信机制,实质上这个机制就是一个回调函数链表的操作,回调函数的注册,注销,调用。
- sleep(睡眠):当用户想要暂停当前进程一段时间时,使用此系统调用。它使资源保持锁定状态,直到睡眠时间结束,然后再次开始执行该过程。在这里,过程在整个执行过程中都有控制权。例如,我在bash上执行了一些命令,并且希望睡眠一段时间,因为期望从已执行命令中获得一些输出,这些输出将在当前进程的进一步执行中使用。