一:wait命令作用

wait是用来阻塞当前进程的执行,直至指定的子进程执行结束后,才继续执行。使用wait可以在bash脚本“多进程”执行模式下,起到一些特殊控制的作用。

二:使用格式

wait [进程号 或 作业号]
eg:wait 23   or  wait %1

如果wait后面不带任何的进程号或作业号,那么wait会阻塞当前进程的执行,直至当前进程的所有子进程都执行结束后,才继续执行。
wait命令用来等待指令的指令,直到其执行完毕后返回终端。
该指令常用于shell脚本编程中,待指定的指令执行完成后,才会继续执行后面的任务。如果该指令等待作业时,在作业标识号前必须添加备份号"%"。

三:举例

以下案例均在CentOS7上执行

[root@node01 server]# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core)

3.1 案例一

[root@node01 server]# cat 1.sh 
#!/bin/bash
echo "1"
sleep 5 &
echo "3"
echo "4"
wait    # 会等待wait所在bash上的所有子进程的执行结束,本例中就是sleep 5这句
echo "5"

3.2 案例二:函数中使用wait

#!/bin/bash
fun() {
        echo "fun is begin.timeNum: $1"
        local timeNum=$1
        sleep $timeNum &
        wait
        echo "fun is end.timeNum: $timeNum"
}
fun 10 &
fun 5 &
wait    # 如果fun里面没有wait,则整个脚本立刻退出,不会等待fun里面的sleep,fun里的sleep语句依然会在后台执行完
echo "all is ending"

1:加上两个wait的执行结果

fun is begin.timeNum:10
fun is begin.timeNum:5
fun is end.timeNum:5
fun is end.timeNum:10
all is ending  # 这句话等最后一个“fun is end.timeNum:10”打印完毕后才会输出

2:不加两个wait的执行结果

all is ending
[root@node01 server]# fun is begin.timeNum: 10
fun is end.timeNum: 10
fun is begin.timeNum: 5
fun is end.timeNum: 5
                      # 注意:这里不是特地加了一个空行,而是脚本执行完成以后光标就一直停在这里

3.3 案例三

command
wait
echo "$?"
# 脚本里这么写echo "$?"打印的是wait命令的执行结果,不是command的执行结果,因为wait本身是一个命令;
command
wait "$PID"
echo "$?"

3.4 案例四

cat test1 | uniq > newtest1 &
cat test2 | uniq > newtest2 &
wait
diff newtest1 newtest2

# 为了比较newtest1和newtest2的不同,必须先让以上的两个cat命令成功并执行完成并生成newtest1和newtest2,否则diff的执行将
# 错误。。。而wait就是保证以上命令执行完成之后才执行diff命令....在以上命令执行完成之前是不会执行diff命令的

四:串行执行与并行执行

我们知道shell中的命令都是串行执行的,如果想要充分利用服务器的资源,就需要些小技巧了。
假定业务上多个业务逻辑没有先后关系,每个脚本的执行时间也很长 ,推荐并行执行。

4.1 串行执行

使用1.sh和2.sh两个脚本模拟业务逻辑

[root@node01 server]# cat 1.sh 
#!/bin/bash
echo '1.sh 开始执行......'
echo '模拟业务逻辑,sleep 5秒,duang duang duang ~~~'
sleep 5s
echo '1.sh 执行结束......'
[root@node01 server]# cat 2.sh 
#!/bin/bash
echo "2.sh 开始执行....."
echo "模拟业务逻辑,sleep 5秒, duang duang  duang~~~"
sleep 5s
echo "2.sh 执行结束....."

我们将脚本放到 call_seria.sh脚本中

[root@node01 server]# cat call_seria.sh 
#!/bin/bash
#当前目录下执行如下脚本  相对路径
./1.sh 
./2.sh 
echo "继续执行剩下的逻辑..."

执行 call_seria.sh脚本(注意给脚本加上执行权限)
Linux shell中的wait命令的使用
由上面的 call_seria.sh脚本执行结果可知为串行执行

4.2 并行执行

使用&和wait改造
在每个进程中使用&符号进行让脚本在后台运行,无需等待当前进程结束。
为了确保每个进程都执行完成,最后务必使用wait关键字,用来确保每一个子进程都执行完成。

[root@node01 server]# cat call_seria.sh 
#!/bin/bash
#当前目录下执行如下脚本  相对路径
./1.sh &
./2.sh &
wait
echo "继续执行剩下的逻辑..."

执行看下效果:
Linux shell中的wait命令的使用
由上面的 call_parallel.sh 脚本执行结果可知为并行执行
通过上述的改造,可以大大的提高多个进程并发执行的效率。 对于可以同时执行的业务逻辑,可以充分利用主机资源,减少等待时间。

4.3 串行与并行执行效率对比

串行执行的时间

[root@node01 server]# cat seria.sh 
#!/bin/bash
beginTime=`date +%s`
num=1
for i in `seq 1 3`
do
        echo $i  "业务逻辑 开始执行,当前时间:" `date "+%Y-%m-%d %H:%M:%S"`
        sleep 2s
        echo $i  "业务逻辑 执行完成,当前时间:" `date "+%Y-%m-%d %H:%M:%S"`
        echo "-----------------------------------------------------------"
done
endTime=`date +%s`
echo "总共耗时:" $(($endTime-$beginTime)) "秒"

执行结果
Linux shell中的wait命令的使用
从执行结果来看,串行,每个进程都要耗时2秒,3个进程6秒处理完成
使用&和wait关键字来改造上上述脚本,使其并行执行

[root@node01 server]# cat parallel.sh   
#!/bin/bash
beginTime=`date +%s`
num=1
for i in `seq 1 3`
do
{
        echo $i  "业务逻辑 开始执行,当前时间:" `date "+%Y-%m-%d %H:%M:%S"`
        sleep 2s
        echo $i  "业务逻辑 执行完成,当前时间:" `date "+%Y-%m-%d %H:%M:%S"`
        echo "-----------------------------------------------------------"
        # 结尾的&确保每个进程后台执行
} &
done
# wait关键字确保每一个子进程都执行完成
wait
endTime=`date +%s`
echo "总共耗时:" $(($endTime-$beginTime)) "秒"

执行结果:
Linux shell中的wait命令的使用
从执行结果来看,并行,同时启动3个进程,3个进程2秒处理完成。

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐