• Shell多进程获取未使用IP方法


    1、需求

        查找192.168.0.*网段中所有未使用过的IP

    2、实现

        我们知道查找未使用IP的方法可以使用ping命令完成。对于单个IP的判断,使用命令如下

    $ ping -c 1 192.168.0.1
    PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
    64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=0.031 ms
    
    --- 192.168.0.1 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.031/0.031/0.031/0.000 ms

      如果上述类似消息,则判断该IP是连通的即在使用中。如果没有,则可以判断未使用(这里不考虑对端服务器ping被禁用的情况)。如果只是查找一个IP,可以多试几个就知道了,但是这种效率太低,可以写个循环批量查找下。

    #!/bin/bash
    
    for i in $(seq 0 255);do
        ip="192.168.0.${i}"
        ping -c 1 ${ip} &>/dev/null
        [ $? -ne 0 ] && printf "${ip} can not reachable
    "
    done

       这个例子实现了批量查找192.168.0.*网段内未使用过的IP。但是执行时候发现效率很低,可以自己执行看下运行效果。显然,这没有解决效率的问题。这时我们考虑使用多进程解决这个问题。看下面例子。

    #!/bin/bash
    
    MAX_THREAD_NUM=50
    
    for i in $(seq 0 255);do
        ip="192.168.0.${i}"
        (
          ping -c 1 ${ip} &>/dev/null
          [ $? -ne 0 ] && printf "${ip} can not reachable
    "
          )&
        num_ping=`ps -ef | grep "ping" | grep -v grep | wc -l`
        while [ "${num_ping}" -gt "${MAX_THREAD_NUM}" ];do
          sleep 1
          num_ping=`ps -ef | grep "ping" | grep -v grep | wc -l`
        done
    done
    wait

        执行发现效率数倍提升。上述的例子是利用&将进程放到后台执行,并且通过循环判断当前ping命令执行的进程数来控制进程数量。这里MAX_THREAD_NUM设置的为50,考虑ping不太消耗资源可以还可以调整更大。如果是消耗资源多的命令应该将MAX_THREAD_NUM调小。具体根据服务器性能和命令消耗资源情况调整。

      还有一种利用文件描述符、read的方法,我们一块写下看下,效果是一样的,例子如下

    #!/bin/bash
    
    temp_fifofile="/tmp/$$.fifo"
    mkfifo ${temp_fifofile}
    exec 5<>${temp_fifofile}
    rm ${temp_fifofile}
    
    MAX_THREAD_NUM=50
    for ((i=0;i<${MAX_THREAD_NUM};i++));do
      echo
    done >&5
    
    for((i=0;i<=255;i++));do
      read -u5
      (
        ip="10.135.17.${i}"
        ping -c 1 ${ip} &>/dev/null
        [ $? -ne 0 ] && printf "${ip} can not reachable
    "
         echo >&5
       )& 
    done
    wait
    exec 5>&-
    exit 0

          如果是其他需要多进程执行的命令,可以修改一下。根据实际情况选择这两种方法之一实现。方法一相对更好理解。

  • 相关阅读:
    Java 线程池概念、原理、简单实现
    Java 中的等待唤醒机制透彻讲解
    Java 多线程安全问题简单切入详细解析
    理解 Java 多线程
    Java 异常的处理
    Android MediaPlayer的生命周期
    Node.js 撸第一个Web应用
    Android简易实战教程--第三十四话《 自定义SeekBar以及里面的一些小知识》
    使用Intent传递对象
    Android 异步查询框架AsyncQueryHandler的使用
  • 原文地址:https://www.cnblogs.com/linyfeng/p/7352331.html
Copyright © 2020-2023  润新知