shell脚本统计ip数

有统计访问用户地理位置的需求,故通过对用户访问信息中ip地址的处理,来整理出用户ip地址和地理位置

文件格式如下:

1555315829.907 ad170ef2-35bf-11e9-906b-286ed488c99f [2019-04-15T16:10:29+08:00] elb 49.69.197.165:64361
1555315830.429 ad170ef2-35bf-11e9-906b-286ed488c99f [2019-04-15T16:10:30+08:00] elb 14.30.43.217:12104

由于可从ip地址查找出地理位置信息,所以先对ip地址数据进行整理,主要的操作有去重和排序。

#!/bin/bash
path=$1;
gzip -d $path/*;
files=$(ls $path);
source_file="filename";
ans_file="filename";
for filename in $files
do
    cat $filename >> $source_file;
done
cat $source_file |awk '{print $5}'|awk -F ':' '{print $1}'|sort -g|uniq > $save_file;

得到整理好的ip地址数据后,就需要查找到它们一一对应的地理位置。
我了解到的有以下几种方法:

(1)whois 命令工具

whois 119.26.15.14
whois.png

输出信息比较多,我们可以提取自己想要的,如 grep 'country'。
但在实际使用过程中,发现其提供的部分ip地址的地理位置信息不完整,故放弃。

(2) 使用网上提供的接口

https://www.ipip.net/support/api.html
https://ip.sb/api/
...
由于是使用shell,推荐第一个接口,速度快但免费的限制次数为1000

temp=$(curl cip.cc/$ip|grep '地址'|awk '{print $3,$4}');

生成文件格式如下


image.png

为更好的查看地理位置,再使用一次sort排序整理

sort -k 2 oversea_ip_addr.txt > oversea.txt;

在实际运行脚本的过程中,发现接口返回的速度实在太慢,12000+ip实际运行了6,7个小时(ps 百兆宽带,肯定不是网速的问题)。基于目前水平,深层的原因暂时没有找到,故为了提高速度,使用shell多进程。

在shell脚本里面,直接使用 & 即可让程序在后台运行,实现方式较为简单。
唯一要注意的是,由于是多进程同时写同一个文件,有可能会出现不同进程同时写入导致乱序或者其他意外情况,所以在这里,我们要使用文件锁,shell脚本对应的命令为 flock 。详细使用方法可以使用man 来查询

(
         flock -n 9 || exit 1
         # ... commands executed under lock ...
       ) 9>/var/lock/mylockfile
              The form is convenient inside shell scripts.   The  mode  used  to  open  the  file
              doesn't matter to flock; using > or >> allows the lockfile to be created if it does
              not already exist, however, write permission is required.  Using  <  requires  that
              the file already exists but only read permission is required.

在这里()后面的内容是先与()里面的内容执行的,“9>/var/lock/mylockfile” 代表的是 文件描述符 与 mylockfile文件写关联,若mylockfile不存在则新建。()里面的数字9即代表文件描述符。

编写完成多进程执行脚本的时候,开启10个进程理论上来说速度应该能达到原来的10倍,实际上只有2倍左右,具体原因待查找。

batch=$1;
process=$2;

path="/mnt/hgfs/共享文件夹/";
source_file=$path"ans.txt";
CN_save_file=$path"CN_ip_addr.txt";
HK_MO_TW_save_file=$path"HK_MO_TW_ip_addr.txt";
oversea_save_file=$path"oversea_ip_addr.txt";

CNlock="/tmp/cn.lock";
HMTlock="/tmp/hmt.lock";
oslock="/tmp/os.lock";

line=$(wc -l $source_file|awk '{print $1}');

startline=$((1+(batch-1)*line/process));
if [ "$batch" == "$process" ];then
        endline=$line;
else
        endline=$((batch*line/process));
fi

ip_total=$(sed -n ${startline},${endline}p $source_file);

for ip in $ip_total
do
        temp=$(curl --max-time 5 cip.cc/$ip|grep '地址'|awk '{print $3,$4}');
        while [ "$temp" == "" ]
        do
                temp=$(curl --max-time 15 cip.cc/$ip|grep '地址'|awk '{print $3,$4}');
        done
        country=$(echo $temp|awk '{print $1}');
        province=$(echo $temp|awk '{print $2}');
        if [ "$country" == "中国" ];then
                case $province in
                        "香港")
                                (
                                flock -w 10 101
                                echo $ip $province >> $HK_MO_TW_save_file
                                )101<>/tmp/hmt.lock
                                ;;
                        "台湾")
                                (
                                flock -w 10 101
                                echo $ip $province >> $HK_MO_TW_save_file
                                )101<>/tmp/hmt.lock
                                ;;
                        "澳门")
                                (
                                flock -w 10 101
                                echo $ip $province >> $HK_MO_TW_save_file
                                )101<>/tmp/hmt.lock
                                ;;
                        *)
                                (
                                flock -w 10 100
                                echo $ip $province >> $CN_save_file
                                )100<>/tmp/cn.lock
                                ;;
                esac
        else
                (
                flock -w 10 102
                echo $ip $country >> $oversea_save_file
                )102<>/tmp/os.lock
        fi

done

你可能感兴趣的:(shell脚本统计ip数)