Linux shell中的wait命令的使用
Linux shell中的wait命令的使用
一: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脚本(注意给脚本加上执行权限)
由上面的 call_seria.sh脚本执行结果可知为串行执行
4.2 并行执行
使用&和wait改造
在每个进程中使用&符号进行让脚本在后台运行,无需等待当前进程结束。
为了确保每个进程都执行完成,最后务必使用wait关键字,用来确保每一个子进程都执行完成。
[root@node01 server]# cat call_seria.sh
#!/bin/bash
#当前目录下执行如下脚本 相对路径
./1.sh &
./2.sh &
wait
echo "继续执行剩下的逻辑..."
执行看下效果:
由上面的 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)) "秒"
执行结果
从执行结果来看,串行,每个进程都要耗时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)) "秒"
执行结果:
从执行结果来看,并行,同时启动3个进程,3个进程2秒处理完成。
更多推荐
所有评论(0)