博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Shell 脚本进程并发&进程数控制
阅读量:4325 次
发布时间:2019-06-06

本文共 4107 字,大约阅读时间需要 13 分钟。

Shell 都以串行的方式自上而下执行命令,不适用需要大量作业的场景。

学习此篇shell脚本进程并发,能够大大提高工作效率~
通过wait 和 & 后台符号 可以实现并行,但无法控制进程数。

{    task}&donewait

{} 将主执行程序变为一个块,使用&放入后台

wait 函数等待所有后台进程执行程序,否则继续执行后续命令直到整个脚本结束

通过有名管道控制并发进程数

创建一个fifo文件, 作为进程池, 里面存放一定数目的"令牌".作业运行规则如下: 所有作业排队依次领取令牌; 每个作业运行前从进程池中领取一块令牌, 完成后再归还令牌; 当进程池中没有令牌时, 要运行的作业只能等待. 这样就能保证同时运行的作业数等于令牌数.

管道 = = 》有名管道、无名(匿名)管道

有名管道:mkfilo 创建一个管道文件
有名管道: “cat 1.file | grep ‘xxx’ ” “|” ==》创建一个无名管道,直接作为两个进程的数据通道

exec 自行定义,绑定文件操作符

系统默认三个文件操作符 0、1、2 = = 》 stdin、stdout、stderr

ls /proc/self/fd

模板

#!/bin/bashtrap "exec 6>&-;exec 6<&-;wxit 0" 2#接受2 程序终止(interrupt)信号 "ctrl c" 后的操作。关闭fd6 tmp_fifofile=/tmp/$$.fifo        //$$ 进程pid  mkfifo $tmp_fifofile             //创建为进程pid的管道                               //我常用$((RANDOM)),大概率的避免与已有文件重复exec 6<>$tmp_fifofile           //以6为文件描述符fd打开管道 <>代表读写rm $tmp_fifofilethread=250                      //定义并发进程数量,上文的令牌数量#在fd6中放入$thread 个空行作为令牌for ((i=0; i<=$thread;i++))do  echodone >&6for i in ``                              //可以省略,直接在{}括号内添加执行命令do    read -u6                             //read 读取行,领取令牌                  {    echo >& 6                            //归还令牌}&                                       //{ }&放入后台donewait                                     //等待所有后台子进程结束exec 6>&-                                //关闭fd6exec 6<&-                                //关闭fd6

结束

学术不精。欢迎评论一起讨论!~

附上一个自己写的使用并发,检查大批量站点的域名检测脚本

将待检查的脚本放入指定目录就行了~

#!/bin/bash#创建今日目录if [ ! -d "./$(date +%y-%m-%d)" ];then    mkdir -p /script/$(date +%y-%m-%d)fidir=/script/$(date +%y-%m-%d)function global(){#第一次curl检测tmp_fifofile=/tmp/$(($RANDOM%1000)).fifomkfifo $tmp_fifofileexec 6<>$tmp_fifofilerm $tmp_fifofilethread=256for ((i=0; i<=$thread;i++))do   echodone >&6for ((i=0;i<=$thread;i++))do    echo >&6donefor i  in `cat /script/domain/$url`do   read -u6   {   code=$(curl -o /dev/null --retry 2 --connect-timeout 10 -s -w %{http_code} $i)   echo "$code $i" >> $dir/$url-first.log   echo >& 6}&donewaitexec 6>&-exec 6<&-grep -v '200\|301\|302'  $dir/$url-first.log  |tail -n +2  |awk -F' ' '{print $2}' > $dir/$url-second.logrm -f $dir/$url-first.log  #第二次wget检测tmp_fifofile=/tmp/$(($RANDOM%1000)).fifomkfifo $tmp_fifofileexec 6<>$tmp_fifofilerm $tmp_fifofilethread=128for ((i=0; i<=$thread;i++))do   echo >&6donefor i in `cat $dir/$url-second.log`do   read -u6   {    wget -T 10 --spider -t 2 $i &>/dev/null $i >> /dev/null    if [ $? = 0 ];then     echo $i >> /dev/null    else     echo $i >> $dir/$url-third.log    fi   echo >& 6}&donewaitexec 6>&-exec 6<&-rm -f $dir/$url-second.log#第三次curl检测tmp_fifofile=/tmp/$(($RANDOM%1000)).fifomkfifo $tmp_fifofileexec 6<>$tmp_fifofilerm $tmp_fifofilethread=128for ((i=0; i<=$thread;i++))do   echo >&6donefor i  in `cat $dir/$url-third.log`do   read -u6   {   code=$(curl -o /dev/null --retry 2 --connect-timeout 10 -s -w %{http_code} $i)   echo "$code $i" >> $dir/$url-fourth.log   echo >& 6}&donewaitexec 6>&-grep -v '200\|301\|302'  $dir/$url-fourth.log  |tail -n +2   >> $dir/last.logrm -f $dir/$url-third.logrm -f $dir/$url-fourth.log}function last (){grep -v '200\|301\|302' $dir/last.log |awk -F' ' '{print $2}' >> $dir/last2.log rm -f $dir/last.logtmp_fifofile=/tmp/last.fifomkfifo $tmp_fifofileexec 6<>$tmp_fifofilerm $tmp_fifofilethread=64for ((i=0; i<=$thread;i++))do   echodone >&6for ((i=0;i<=$thread;i++))do    echo >&6donefor i  in `cat $dir/last2.log`do   read -u6   {   code=$(curl -o /dev/null --retry 2 --connect-timeout 10 -s -w %{http_code} $i)   echo "$code $i" >> $dir/last3.log   echo >& 6}&donewaitexec 6>&-exec 6<&-rm -f $dir/last2.logecho "请手动复核以下域名:" > $dir/$(date +%H-00)domain.loggrep -v '200\|301\|302' $dir/last3.log >> $dir/$(date +%H-00)domain.logrm -f $dir/last3.log}function main (){tmp_fifofile=/tmp/main.fifomkfifo $tmp_fifofileexec 8<>$tmp_fifofilerm $tmp_fifofilethread=2for ((i=0; i<=$thread;i++))do   echodone >&8for url in `ls -l /script/domain/ | tail -n +2 | awk -F' ' '{print $9}'`do  read -u8{  global $url  echo >& 8}&donewaitexec 8>&-exec 8<&-}mainlastmail -s "检测结果来自xx服务器 :" xxxxxxxx@qq.com < $dir/$(date +%H-00)domain.log

转载于:https://www.cnblogs.com/hehehe886/p/9150418.html

你可能感兴趣的文章
机器学习基石笔记2——在何时可以使用机器学习(2)
查看>>
POJ 3740 Easy Finding (DLX模板)
查看>>
MySQL 处理重复数据
查看>>
关于typedef的用法总结(转)
查看>>
【strtok()】——分割字符串
查看>>
Linux下安装rabbitmq
查看>>
曹德旺
查看>>
【转】判断点在多边形内(matlab)
查看>>
java基础之集合:List Set Map的概述以及使用场景
查看>>
Python 线程 进程 协程
查看>>
iOS语言中的KVO机制
查看>>
excel第一次打开报错 向程序发送命令时出错 多种解决办法含终极解决方法
查看>>
响应式web设计之CSS3 Media Queries
查看>>
实验三
查看>>
机器码和字节码
查看>>
环形菜单的实现
查看>>
【解决Chrome浏览器和IE浏览器上传附件兼容的问题 -- Chrome关闭flash后,uploadify插件不可用的解决办法】...
查看>>
34 帧动画
查看>>
二次剩余及欧拉准则
查看>>
Centos 7 Mysql 最大连接数超了问题解决
查看>>