造轮子之 Linux/macOS下编写自己的ip查询指令

事情源于发现开源项目:Github | 准确率99.9%的ip地址定位库

每次查IP都要开浏览器、输网址、输IP的过程让我等懒人很是烦躁,遂尝试写一个bash脚本,简化查IP的过程

  • Github | 准确率99.9%的ip地址定位库 此项目(我使用python3版本)
  • python环境(2、3均可,源项目都提供支持)
  • java环境(为更新IP数据库而准备)
    • macOS使用brew-cask安装:
      brew cask install java

满足以上三个条件就能开始了,整体难度并不大

  1. clone下来ip2region项目后,先运行python3下的testSearcher.py:
  2. 修改示例程序,去掉其输入,改为接受IP地址参数,并去除了其他不必要的输出
    • 稍微修改后的代码
      #-*- coding:utf-8 -*-
      import struct, sys, os, time
      from ip2Region import Ip2Region
      
      def testSearch():
      
          llen = len(sys.argv) 
          dbFile    = "./ip2region.db" # IP数据库路径
          method    = 1 # 默认b树
          ip = sys.argv[1] # 接受IP参数
      
          if (not os.path.isfile(dbFile)) or (not os.path.exists(dbFile)):
              print ("[Error]: Specified db file is not exists.")
              return 0
      
          searcher = Ip2Region(dbFile);
      
          while True:
              line = ip
              line = line.strip()
      
              if line == "":
                  print ("[Error]: Invalid ip address.")
                  continue
      
              if line == "quit" or line == "exit" :
                  print ("[Info]: Thanks for your use, Bye.")
                  break
      
              if not searcher.isip(line):
                  print ("[Error]: Invalid ip address.")
                  continue
      
              if method == 1:
                  data = searcher.btreeSearch(line)
              elif method == 2:
                  data = searcher.binarySearch(line)
              else:
                  data = searcher.memorySearch(line)
      
              if isinstance(data, dict):
                  print ("%s|%s" % (data["city_id"], data["region"].decode('utf-8'))) # 去除时间输出
              else:
                  print ("[Error]: ", data)
              break # 一次查询后直接退出
      
          searcher.close()
      
      if __name__ == "__main__":
          testSearch()
    • 修改后的输出:
  3. 修改后的输出不够完美, 又通过sed去除了城市编号和数字0(城市编号也可以通过删除输出语句的“data[“city_id”]”实现)
    • 指令
      python3 testSearcher.py 1.1.1.1 | sed 's/[0-9]//g; s/||/|/; s/$/&|/g'
    • 输出结果:
  4. 接下来编写bash脚本,将上一步的指令写入文件即可
    • 代码
      #! /bin/sh
      if [ -z "$1" ]
      then
          echo "Usage: iplookup [IP Address]" # 我的脚本名为iplookup
      else
          python3 [Your Path]/testSearcher.py $1 | sed 's/[0-9]//g; s/||/|/; s/$/&|/g'
      fi
    • 将写好的脚本链接到/usr/local/bin/,并给授予脚本权限
      ln -s [your bash script path] /usr/local/bin/[your script name]
      chmod +x [your bash script path]
  5. 之后就可以通过键入“[你的脚本名] [IP地址]”来查询IP了:
  6. 最后,编写更新数据库的脚本,此时就用到了java环境
    • 查看源项目中的更新指令
      java -jar dbMaker-{version}.jar -src 文本数据文件 -region 地域csv文件 [-dst 生成的ip2region.db文件的目录]

       

      # 文本数据文件:db文件的原始文本数据文件路径,自带的ip2region.db文件就是/data/ip.merge.txt生成而来的,你可以换成自己的或者更改/data/ip.merge.txt重新生成 # 地域csv文件:该文件目的是方便配置ip2region进行数据关系的存储,得到的数据包含一个city_id,这个直接使用/data/origin/global_region.csv文件即可 # ip2region.db文件的目录:是可选参数,没有指定的话会在当前目录生成一份./data/ip2region.db文件
    • 将路径替换为本地路径后,写入脚本。原指令成功执行后会输出一大坨IP信息,不利于终端执行,遂在java指令前加nohup将其输出到nohup.out,然后再添加rm nohup.out删除之
      nohup java -jar /Project/ipregion/dbMaker-1.2.2.jar -src /Project/ipregion/ip.merge.txt -region /Project/ipregion/global_region.csv -dst /Project/ipregion/
      rm /Project/ipregion/nohup.out
      
    • 运行ipupdate(我的脚本名),可以看到没有长串的输出,同时也删除了nohup.out: