介紹如何在 Bash 指令稿中使用 wait
來等待指定工作完成。
Bash 中的
wait
指令可以用來等待指定工作結束,並取得工作的傳回值,以下是 wait
指令的用法教學與範例程式碼。
等待所有工作結束
Bash 的 wait
指令可用於等待背景工作執行結束,當執行 wait
指令不帶任何參數時,預設會等待所有的背景工作結束。
下面這段程式碼中,我們讓兩個測試的工作放在背景執行,接著呼叫 wait
等待所有背景工作執行完畢,最後再輸出結束工作的訊息:
#!/bin/bash # 背景執行兩個工作 echo `date +"%T"` "背景執行兩個工作" sleep 1 && echo `date +"%T"` "完成工作一" & sleep 3 && echo `date +"%T"` "完成工作二" & # 等待所有工作完成 wait echo `date +"%T"` "結束所有工作"
07:54:05 背景執行兩個工作 07:54:06 完成工作一 07:54:08 完成工作二 07:54:08 結束所有工作
等待其中一個工作結束
如果背景的工作有好多個,而我們只想要等待其中一個工作結束,可以在呼叫 wait
時加上 -n
參數:
#!/bin/bash # 背景執行三個工作 echo `date +"%T"` "背景執行三個工作" sleep 2 && echo `date +"%T"` "完成工作一" & sleep 1 && echo `date +"%T"` "完成工作二" & sleep 3 && echo `date +"%T"` "完成工作三" & # 等待其中一個工作完成 wait -n echo `date +"%T"` "其中一個工作完成"
08:00:50 背景執行三個工作 08:00:51 完成工作二 08:00:51 其中一個工作完成 08:00:52 完成工作一 08:00:53 完成工作三
若要判斷是哪一個工作第一個完成,可以加上 -p
參數並指定一個變數名稱,這樣第一個完成的行程 PID 就會儲存於該變數中(同時 wait
也會傳回該行程的傳回值)。
#!/bin/bash # 背景執行三個工作 echo `date +"%T"` "背景執行三個工作" sleep 2 && echo `date +"%T"` "完成工作一" & sleep 1 && echo `date +"%T"` "完成工作二" & sleep 3 && echo `date +"%T"` "完成工作三" & # 等待其中一個工作完成 wait -n -p PID echo `date +"%T"` "其中一個工作完成:$PID"
08:58:07 背景執行三個工作 08:58:08 完成工作二 08:58:08 其中一個工作完成:20921 08:58:09 完成工作一 08:58:10 完成工作三
等待指定工作完成
如果要等待指定的工作完成,可以在呼叫 wait
時以參數指定要等待的行程 ID。
在以下的範例中,我們在執行工作之後,透過 $!
變數取得工作行程的行程 ID,然後用於隨後的 wait
參數中,藉由這樣的方式指定要等待的工作。
#!/bin/bash # 背景執行三個工作 echo `date +"%T"` "背景執行三個工作" sleep 2 && echo `date +"%T"` "完成工作一" & PID1=$! sleep 1 && echo `date +"%T"` "完成工作二" & PID2=$! sleep 3 && echo `date +"%T"` "完成工作三" & PID3=$! # 等待工作一完成 echo `date +"%T"` "等待工作一完成:$PID1" wait $PID1 echo `date +"%T"` "工作一完成了"
08:20:36 背景執行三個工作 08:20:36 等待工作一完成:19915 08:20:37 完成工作二 08:20:38 完成工作一 08:20:38 工作一完成了 08:20:39 完成工作三
取得行程傳回值
當呼叫 wait
並指定要等待的行程 ID 時,會傳回該行程結束時的傳回值。因此我們可以在呼叫 wait
之後,透過 $?
取得該行程的傳回值,藉此判斷工作是否執行成功:
#!/bin/bash # 背景執行兩個工作 echo `date +"%T"` "背景執行兩個工作" (sleep 2 && exit 11) & PID1=$! (sleep 1 && exit 22) & PID2=$! # 等待工作一完成 echo `date +"%T"` "等待工作一完成:$PID1" wait $PID1 S1=$? echo `date +"%T"` "工作一結果:$S1" # 等待工作二完成 echo `date +"%T"` "等待工作二完成:$PID2" wait $PID2 S2=$? echo `date +"%T"` "工作二結果:$S2"
08:48:32 背景執行兩個工作 08:48:32 等待工作一完成:20671 08:48:34 工作一結果:11 08:48:34 等待工作二完成:20672 08:48:34 工作二結果:22