python學習寫腳本之從頭至尾實錄

學習python,在老雷的指點下去完成一個小需求

功能:檢索/var/log/secure中的ip,超過閥值就寫入/etc/hosts.deny文件中去
html

一、首先從/var/log/secure中提取ip地址
二、而後進行排序,挑選出訪問量大於500的ip
三、把收集到的ip寫入到hosts.deny文件中,寫入以前先判斷是否已存在python

格式要求以下:nginx

########2014-06-25#######
60.xxx.xxx.xxx
58.xxx.xxx.xxx

########2014-06-26#######
60.xxx.xxx.xxx
58.xxx.xxx.xxx

解決過程

一、首先從/var/log/secure中提取ip地址

# coding: utf-8
# Auther: zhuima
# Date:   2014-06-24
# Function: fetch ip address
# Usage:  python sys.argv[0] logpath
#

import re
import sys

pattern = re.compile(r'(\d+\.\d+\.\d+\.\d+)')

def ip_fetch(logfile):
    with open(logfile) as f:
        for line in f:
            m = pattern.search(line)
            if m:
                print m.group()

if len(sys.argv) == 2:
    ip_fetch(sys.argv[1])
else:
    print "Usage: python %s /path/logfile" % sys.argv[0]
    print " "

效果以下:vim

[root@nginx1 python]# python tiquip.py secure 
114.114.114.114


[root@nginx1 python]# python tiquip.py

 Usage: python tiquip.py /path/logfile

[root@nginx1 python]#

二、進行排序,挑選出排行前十的ip

須要解決問題:去重排序
sorted()排序
set()去重
裸用dict來作得話:
counter = dict()
for ip in m:
counter[ip] = counter.get(ip, 0) + 1bash

http://www.newsmth.net/nForum/#!article/Python/113879
http://hi.baidu.com/pythond/item/3607e6564aacae928d12ed41app

去重(成哥提供的網站)ide

from collections import Counter
Counter([1,1,1,2,3,4,1,2,3,4])
Counter({1: 4, 2: 2, 3: 2, 4: 2})函數

2.一、去重操做

[root@nginx1 python]# cat fetch.py 
# coding: utf-8
# Auther: zhuima
# Date:   2014-06-24
# Function: fetch ip address
# Usage:  python sys.argv[0] logpath
#

from collections import Counter 
import re
import sys

pattern = re.compile(r'(\d+\.\d+\.\d+\.\d+)')
listip = []
def ip_fetch(logfile):
    with open(logfile) as f:
        for line in f:
            m = pattern.search(line)
            if m:
                listip.append(m.group())
                #print m.group()

def sort():
    td = Counter(listip)
    for ip,count in td.items():
        print count,"\t",ip

if len(sys.argv) == 2:
    ip_fetch(sys.argv[1])
    sort()
else:
    print "Usage: python %s /path/logfile" % sys.argv[0]
    print " "

效果以下:學習

[root@nginx1 python]# python fetch.py secure 
1     114.xxx.xxx.xxx
1     114.xxx.xxx.xxx
1     106.xxx.xxx.xxx
4     124.xxx.xxx.xxx
1     61.xxx.xxx.xxx

[root@nginx1 python]#

2.二、接下來進行排序

http://www.cnblogs.com/liyixin/archive/2012/07/23/2605013.html測試

腳本樣式:

# coding: utf-8
# Auther: zhuima
# Date:   2014-06-24
# Function: fetch ip address
# Usage:  python sys.argv[0] logpath
#

from collections import Counter
import re
import sys

pattern = re.compile(r'(\d+\.\d+\.\d+\.\d+)')
listip = []
def ip_fetch(logfile):
    with open(logfile) as f:
        for line in f:
            m = pattern.search(line)
            if m:
                listip.append(m.group())
        

def sort():
    td = Counter(listip)

    newtd = sorted(td.iteritems(),key=lambda td:td[1],reverse=True)
  
    for line in newtd:
        print line

if len(sys.argv) == 2:
    ip_fetch(sys.argv[1])
    sort()
else:
    print "Usage: python %s /path/logfile" % sys.argv[0]
    print " "

效果以下:

[root@nginx1 python]# python fetch.py secure 
('124.64.63.119', 4)
('114.245.169.74', 1)
('114.252.165.177', 1)
('106.37.169.186', 1)
('61.49.238.82', 1)
[root@nginx1 python]#

再次更改,去除數值外面的圓括號

[root@nginx1 python]# vim fetch.py 

# coding: utf-8
# Auther: zhuima
# Date:   2014-06-24
# Function: fetch ip address
# Usage:  python sys.argv[0] logpath
#

from collections import Counter
import re
import sys

pattern = re.compile(r'(\d+\.\d+\.\d+\.\d+)')
listip = []
def ip_fetch(logfile):
    with open(logfile) as f:
        for line in f:
            m = pattern.search(line)
            if m:
                listip.append(m.group())
          
def sort():
    td = Counter(listip)

    newtd = sorted(td.iteritems(),key=lambda td:td[1],reverse=True)

    for line in newtd:
        print line[1],"\t",line[0]

if len(sys.argv) == 2:
    ip_fetch(sys.argv[1])
    sort()
else:
    print "Usage: python %s /path/logfile" % sys.argv[0]
    print " "

效果以下:

[root@nginx1 python]# python fetch.py secure 
4     124.xxx.xxx.xxx
1     114.xxx.xxx.xxx
1     114.xxx.xxx.xxx
1     106.xxx.xxx.xxx
1     61.xxx.xxx.xxx

[root@nginx1 python]#

三、解析來解決如何寫入到hosts.deny文件中去

思路:
先判斷要寫入的ip是否在hosts.deny文件中,若是在,就跳過,若是不在就寫入
腳本測試文件,寫不進文件中去

[root@nginx1 python]# vim write.py

# coding utf-8
#

x = '192.168.23.22'
with open("/etc/hosts.deny","a+") as f:
    for line in f:
        if x not in line:
            f.write(x)
# coding utf-8
#

import datetime

dd = datetime.

x = '192.168.23.22'
f = open("/etc/hosts.deny","a+")
for line in f:
    if x not in f:
        f.write("#########")
        f.write(datetime
        f.write("#########")
        f.write(x)
        f.write("\n")

f.close()

http://blog.sina.com.cn/s/blog_6c3748830100ypt9.html

單個ip驗證的時候

[root@rsync python]# cat write.py
# coding utf-8
#

import datetime


day = datetime.date.today()
today = day.strftime("%Y-%m-%d")

x = ['192.168.23.22','192.168.23.21']
i = 0
f = open("/etc/hosts.deny","a+")
for line in f:
    if x[i] not in line:
        print x[i]
        f.write("#########")
        f.write(today)
        f.write("#########")
        f.write("\n")
        f.write(x[i])
        f.write("\n")
        i += 1
    else:
        print x[i], "is exists!"
        break

f.close()

固然咱們實際環境中不可能只用一個ip,確定會有不少的額,因此這裏就須要使用列表了
多個參數傳入的時候該如何是好

[root@rsync python]# cat write.py
# coding utf-8
#

import datetime


day = datetime.date.today()
today = day.strftime("%Y-%m-%d")

x = ['192.168.23.22','192.168.23.21']
i = 0

f = open("/etc/hosts.deny","a+")
for line in f:
    if x[i] not in line and i <= len(x):
        f.write("#########")
        f.write(today)
        f.write("#########")
        f.write("\n")
        f.write(x[i])
        f.write("\n")
        i += 1
    else:
        print x[i], "is exists!"
        break

上面代碼報錯:

[root@rsync python]# 
[root@rsync python]# python write.py /etc/hosts.deny 
Traceback (most recent call last):
  File "write.py", line 20, in <module>    
  if x[i] not in line and i <= len(x):
IndexError: list index out of range
[root@rsync python]#

踩坑之旅:
一直陷在循環裏面挑不出來了,因此就一直繞啊繞~
問題:
一、嵌套循環沒法解決上層循環的次數比內層循環的次數多的問題,從而致使插入數據過多
二、判斷數據在列表中是否存在的時候總是想着要對比循環
三、基礎薄弱

老雷給的建議:

# coding utf-8
#

import datetime


day = datetime.date.today()
today = day.strftime("%Y-%m-%d")

ip_list = ['192.168.23.22','192.168.23.21']

data = open("/etc/hosts.deny","a+")

content_list = data.readlines()

for i in ip_list:
    if i not in content_list:
        data.write(i+'\n')
f.close()

最總完結的腳本:

[root@blog python]# cat fetch.py 
# coding: utf-8
# Auther: zhuima
# Date:   2014-06-24
# Function: fetch ip address
# Usage:  python sys.argv[0] logpath
#


from collections import Counter
import re
import sys
import datetime

pattern = re.compile(r'(\d+\.\d+\.\d+\.\d+)')

source_listip = []

today = datetime.date.today().strftime("%Y-%m-%d")

def ip_fetch(logfile):
    with open(logfile) as f:
        for line in f:
            m = pattern.search(line)
            if m:
                source_listip.append(m.group())
              

def sort_write():
    data_file = open("/etc/hosts.deny","a+")
    content_list = data_file.readlines()
    note = ["########",today,"#######\n"]
    td = Counter(source_listip)
 
    newtd = sorted(td.iteritems(),key=lambda td:td[1],reverse=True)


    for line in content_list:
        if today in line.strip("#"):
            break
        else:
            data_file.writelines(note)
            break


    for line in newtd:
        print line[1],"\t",line[0]
        if line[1] >= 500 and line[0] not in content_list:
            data_file.write(line[0]+"\n")

    data_file.close()


if len(sys.argv) == 2:
    ip_fetch(sys.argv[1])
    sort_write()

else:
    print "Usage: python %s /path/logfile" % sys.argv[0]

效果以下圖所示:

Note:
因爲導入datetime是使用的當前時間,而不是系統時間,因此這裏顯示的兩個時間是一致的
0a79c677-7acc-46d2-95b8-85979b94826e_4_files/524aa759-1ea0-432c-a8f0-0303c3d925ad.pngwKiom1Oqp4mjr0vsAANQBTMbd-0030.jpg

總結:

感謝斌哥的思路指導,感謝成哥的Counter的思路提供,感謝老雷的一路指導~一、基礎知識掌握太弱二、寫的過程當中總是急於求成,沒有精心來去思考三、多看官方文檔,建議把標準庫查看一遍四、該腳本很爛,後期繼續以函數的形式來寫

相關文章
相關標籤/搜索