如何写shell脚本,如何实现同时给三台ftp服务器上传文件,如何同时检测三台服务器是否alive等,其实这就是想实现shell的并发。 那么shell并发该如何实现呢?
还是以例子来作讲解: 按照正常思维,脚本应该这样写:
复制代码代码如下:
[root@station1 ~]# cat a.sh #!/bin/bash for((i=0;i<20;i++)) do sleep 1 echo "bingfa" done [root@station1 ~]# time bash a.sh bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa real 0m20.067s user 0m0.016s sys 0m0.031s [root@station1 ~]#
可以看到执行此脚本大概用了20秒。那么使用shell并发该怎么写,很多人都会想到后台程序,类似如下:
复制代码代码如下:
[root@station1 ~]# cat b.sh
#!/bin/bash for((i=0;i<20;i++)) do { sleep 1 echo "bingfa" }& done wait [root@station1 ~]# time bash b.sh bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa bingfa real 0m1.060s user 0m0.005s sys 0m0.057s [root@station1 ~]#
这样写只需花大概一秒钟,可以看到所有的任务几乎同时执行,如果任务量非常大,系统肯定承受不了,也会影响系统中其他程序的运行,这样就需要一个线程数量的控制。下面是我一开始写的代码(是有问题的):
复制代码代码如下:
[root@station1 ~]# cat c.sh
#!/bin/bash exec 6<>tmpfile echo "1n1n1" &>6 for((i=0;i<20;i++)) do read -u 6 { sleep 1 echo "$REPLY" echo "1" 1>&6 }& done wait [root@station1 ~]# time bash c.sh 111 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 real 0m1.074s user 0m0.012s sys 0m0.031s [root@station1 ~]#
可以明显看出是有问题的,我本想控制线程个数为3,但是就算文件描述符6中为空,也会被读取空,然后跳过继续下面的执行,所以使用文件描述符打开一个文件是不行的,然后我就想着使用类似管道的文件来做,下面是我的代码:
复制代码代码如下:
[root@station1 ~]# cat d.sh
#!/bin/bash mkfifo fd2 exec 9<>fd2 echo -n -e "1n1n1n" 1>&9 for((i=0;i<20;i++)) do read -u 9 { #your process sleep 1 echo "$REPLY" echo -ne "1n" 1>&9 } & done wait rm -f fd2 [root@station1 ~]# time bash d.sh 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 real 0m7.075s user 0m0.018s sys 0m0.044s [root@station1 ~]# 这样就可以了,三个线程运行20个任务,7秒多点。 |