shell实战案例-批量ping ip(多进程限制并发)

目录

批量ping IP

如何使用多进程处理呢?

如何限制并发呢?

 代码实现


批量ping IP

要点:

1. 定义trap 捕捉INT信号,以便退出。

2. 生成序列的方式可以使用{} , 也可以使用seq 2 254

seq -w 还可以等位补齐,很好用

3.ping

-c 参数代表次数。不会像windows一样ping四次后停止,次数由用户指定.

-W 代表timeout,1表示的是超过三秒钟就定义为ping不通

4.ping -c1 -W1 $ip &>/dev/null  将ping的STDOUT个STDERR 输出到黑洞文件.

5. echo "$ip" | tee -a ip.txt 代表 输出控制台的同时也追加写到ip.txt

#!/bin/bash
  
#批量 ping ip 是否可以ping 通  ping 同网段的ip
# 2022年1月2日15:51:02

trap "echo trapped!;exit 1" SIGINT SIGTERM SIGQUIT SIGHUP
> ip.txt
for i in {2..254};do
        ip=8.142.104.$i
        ping -c1 -W1 $ip &>/dev/null
        if [ $? -eq 0 ];then
                echo "$ip" | tee -a ip.txt
                #sleep 1s
        fi
done

ping操作比较省时间,如果是个复杂的事情,在一个bash进程中处理太慢了

如何使用多进程处理呢?

脚本稍加改造:

多进程很好实现,将for循环体用{} &放入后台执行即可。

#!/bin/bash

#批量 ping ip 是否可以ping 通  ping 同网段的ip
# 2022年1月2日15:51:02

trap "echo trapped!;exit 1" SIGINT SIGTERM SIGQUIT SIGHUP
> ip.txt
for i in {2..254};do
	{
	ip=8.142.104.$i
	ping -c1 -w1 $ip &>/dev/null
	if [ $? -eq 0 ];then
		echo "$ip" | tee -a ip.txt
	fi		
	} &
done	
echo "finish...."

 这个结果好像不太对,finish...怎么先打印出来了呢?

主进程一下子就执行完了,都在等待子进程的执行,如何让主进程等待其他子进程做完之后再执行呢?

使用wait命令

如何限制并发呢?

多进程是实现了,但是没有限制并发,ping一个网段还好一点,如果要ping 100个网段呢?200个网段呢? 如果不限制并发,机器的性能总有被榨干的时候。

借助管道实现并发控制。

实现思路: 使用一个fd 打开管道,往管道中送一些空行(多少个空行就多少个进程)。

 在bash中通过此方法模拟co-process(协程) 实现不同进程之间的异步通信。

 代码实现

#!/bin/bash
  
#批量 ping ip 是否可以ping 通  ping 同网段的ip
# 2022年1月2日15:51:02

count=$1
#创建管道文件

filename=/tmp/$$.fifo # 当前bash的pid

mkfifo $filename
# 以可读可写方式 用fd8 指向fifo
exec 8<> $filename

#rm -rf $filename # exec 已经指向了这个fifo, 即使删除,这个管道并不会被删除,除非关闭fd8,管道才会消失

#向管道中注入空行,注入多少个取决于你希望的并发量

echo $count
for line in `seq $count`;do
        echo >&8
done

trap "echo trapped!;exit 1" SIGINT SIGTERM SIGQUIT SIGHUP
> ip.txt
for i in {2..254};do
        read -u 8 # 在fd8 中读取内容 read from file descriptor FD instead of the standard inpu
        {
        ip=8.142.104.$i
        ping -c1 -w1 $ip &>/dev/null
        if [ $? -eq 0 ];then
                echo "$ip" | tee -a ip.txt
                sleep 1s
        fi
        echo >&8
        } &
done
wait
exec 8>&- # 释放文件描述符
echo "finish...."

不一定是等三个执行完再执行另外三个,只要管道中能读取到空行就可以执行。可以将参数传2 看的更清楚

思考一个问题: 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MyySophia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值