Shell多线程操作及线程数控制实例_linux shell

前言

在业务开发过程中,经常会在后台写一些shell脚本处理数据,但估计很多人不知道shell脚本也可以支持多线程,而且非常简单。本篇文章主要就是介绍shell实现多进程以及进程数量控制。

需求

为了更好的说明问题,我们结合例子讲解,假设需求就是扫描url.txt文件,然后判断里面的URL是否失效。url.txt文件的内容是一行一个URL,如:

复制代码 代码如下:

http://www.baidu.com

http://www.google.com

http://www.jb51.net

单进程实现

那么shell脚本scanUrl.sh可以这样写:

复制代码 代码如下:

#!/bin/bash
#判断是否有参数
if [ $# != 1 ] ;then
        echo "The parameters you enter is not correct !";
        exit -1;
fi

#循环读出URL并判断状态码
while read line
do
{
    isok=`curl -I -o /dev/null -s -w %{http_code} $line`
    if [ "$isok" = "200" ]; then
        echo $line "OK"
    else
        echo $line "no"
    fi
}
done < $1
echo "执行结束"

那么可以执行下面的命令扫描:

复制代码 代码如下:

/bin/sh scanUrl.sh url.txt

但这样脚本执行非常慢,一万个URL几个小时都扫描不完。

多进程实现

改成多进程实现非常简单,只需要在do后面的大括号加 & 符号,在done后面加一个wait,表示父进程等待子进程退出后再退出

复制代码 代码如下:

#!/bin/bash
#判断是否有参数
if [ $# != 1 ] ;then
        echo "The parameters you enter is not correct !";
        exit -1;
fi

#循环读出URL并判断状态码
while read line
do
{
    isok=`curl -I -o /dev/null -s -w %{http_code} $line`
    if [ "$isok" = "200" ]; then
        echo $line "OK"
    else
        echo $line "no"
    fi
    }
}&
done < $1
wait
echo "执行结束"

这样就能多进程并发执行了,但有个问题是进程会一下子非常多,几百上千,超过系统限制报错,下面我们就加上进程数控制。

多进程实现并控制进程数

复制代码 代码如下:

#!/bin/bash
#允许的进程数
THREAD_NUM=200
#定义描述符为9的管道
mkfifo tmp
exec 9<>tmp
#预先写入指定数量的换行符,一个换行符代表一个进程
for ((i=0;i<$THREAD_NUM;i++))
do
    echo -ne "\n" 1>&9
done

if [ $# != 1 ] ;then
        echo "The parameters you enter is not correct !";
        exit -1;
fi

while read line
do
{
    #进程控制
    read -u 9
    {
        #isok=`curl -I -o /dev/null -s -w %{http_code} $line`
        if [ "$isok" = "200" ]; then
            echo $line "OK"
        else
            echo $line "no"
        fi
        echo -ne "\n" 1>&9
    }&
}
done < $1
wait
echo "执行结束"
rm tmp

上面的代码就可以保证子进程在指定数量了,其进程控制原理是通过管道实现的,当管道无内容可读时就不会执行

复制代码 代码如下:

{
    #isok=`curl -I -o /dev/null -s -w %{http_code} $line`
    if [ "$isok" = "200" ]; then
        echo $line "OK"
    else
        echo $line "no"
    fi
    #写入一个换行符
    echo -ne "\n" 1>&9
}&

而且每个进程执行完成后都会向管道写入一个换行符,从而保证进程数是指定的。

这样就能达到我们的目的了。

时间: 2024-09-30 06:16:25

Shell多线程操作及线程数控制实例_linux shell的相关文章

shell脚本中取消重定向的方法实例_linux shell

在上一篇关于shell编程的例子中,有讲到把shell脚本进行扩展之后重定向到一个文件中,以便进行查看和调试http://www.jb51.net/article/62435.htm.但是,若是有另一种情况:只是在某些地方进行重定向,而其他地方不进行重定向.那么我们就来修改一下上一篇中的例子来进行这种需求的满足: 复制代码 代码如下: #!/bin/bash function setlogfile {     if ! [ -z "$1" ]; then         echo &q

Shell中处理包含空格的文件名实例_linux shell

今天在处理文件时遇到个问题,当文件名包含空格时,for循环就出问题了. 例如,我在当前文件夹下建立3个文件名包含空格的文件: 复制代码 代码如下: keakons-MacBook-Pro:test keakon$ touch "test 1"keakons-MacBook-Pro:test keakon$ touch "test 2"keakons-MacBook-Pro:test keakon$ touch "test 3"keakons-Ma

Shell脚本去重的几种方法实例_linux shell

测试文件 复制代码 代码如下: [root@bogon ~]# cat >test jason jason jason fffff jason 按 Ctr + D保存 1.sort -u 复制代码 代码如下: [root@bogon ~]# sort -u test fffff jason 2.uniq 复制代码 代码如下: [root@bogon ~]# uniq test jason fffff jason 由此可见,uniq需要先排序后才能去重 3.sort.管道和uniq结合运用 去除重

Shell脚本test命令使用总结和实例_linux shell

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值.字符和文件三个方面的测试. 数值测试 参数 说明 -eq 等于则为真 -ne 不等于则为真 -gt 大于则为真 -ge 大于等于则为真 -lt 小于则为真 -le 小于等于则为真 例如: 复制代码 代码如下: num1=100 num2=100 if test $[num1] -eq $[num2] then     echo 'The two numbers are equal!' else     echo 'The t

Shell脚本检查IP格式及mysql操作实例_linux shell

还是cronjob的一部分,就是在Rails的定时任务里,后台交互运行 CheckIPAddress() { echo $1 |grep "^[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}$" > /dev/null if [ $? = 1 ]; then return 1 else a=`echo $1 | awk -F. '{print $1}'` b=`echo $1 | awk -F. '{print $2}'

用shell脚本监控进程是否存在 不存在则启动的实例_linux shell

用shell脚本监控进程是否存在 不存在则启动的实例,先上代码干货: #!/bin/sh ps -fe|grep processString |grep -v grep if [ $? -ne 0 ] then echo "start process....." else echo "runing....." fi ##### processString 表示进程特征字符串,能够查询到唯一进程的特征字符串 0表示存在的 $? -ne 0 不存在,$? -eq 0 存

Linux系统中bash shell编程的10个基础问题讲解_linux shell

第1问:为何叫做shell?在介绍 shell 是什么东西之前,不妨让我们重新审视使用者与电脑的关系.我们知道电脑的运作不能离开硬件,但使用者却无法直接对硬件作驱动,硬件的驱动只能透过一个称为"操作系统(Operating System)"的软件来控管,事实上,我们每天所谈的linux,严格来说只是一个操作系统,我们称之为"核心(kernel)".然而,从使用者的角度来说,使用者也没办法直接操作kernel,而是透过kernel的"外壳"程序,也

Shell脚本中获取进程ID的方法_linux shell

提问: 我想要知道运行中脚本子shell的进程id.我该如何在shell脚本中得到PID. 当我在执行shell脚本时,它会启动一个叫子shell的进程.作为主shell的子进程,子shell将shell脚本中的命令作为批处理运行(因此称为"批处理进程"). 在某些情况下,你也许想要知道运行中的子shell的PID.这个PID信息可以在不同的情况下使用.比如,你可以使用shell脚本的PID在/tmp下创建一个唯一的临时文件.有时侯脚本需要检测所有运行的进程,它可以从进程列表中排除自身

Shell交互批量更改主机名的方法_linux shell

需求分析:      1.ssh公钥拷贝,提供无密码管理.      2.批量同步hosts文件到多台主机.      3.批量修改主机名. 实现: 首先编辑一份用于同步到多台主机的hosts文件 vi /etc/hosts 192.168.0.1 server1 192.168.0.2 server2 192.168.0.3 server3 192.168.0.4 server4 192.168.0.5 server5 192.168.0.6 server6 192.168.0.7 serve