shell指令碼案例分享 - 業務系統日誌自定義保留或刪除需求

散盡浮華發表於2018-12-13

 

需求說明:  線上某些業務系統的日誌不定期產生, 有的每天產生, 有的好幾天才產生, 因為系統只有在用的時候才產生日誌,日誌檔案均存放在以當天日期命名的目錄下. 當日志目錄越來越多時就需要處理, 由此開發同事提出來一個需求, 需要一個自定義刪除或保留這些日誌目錄的指令碼, 如下:

[root@localhost pay-sign-oper]# ls
2018-09-13  2018-09-20  2018-10-11  2018-10-28  2018-11-02  2018-11-14  2018-12-04  2018-12-09          
2018-09-14  2018-09-27  2018-10-24  2018-10-29  2018-11-06  2018-11-15  2018-12-05  2018-12-10
2018-09-15  2018-09-29  2018-10-25  2018-10-30  2018-11-07  2018-11-30  2018-12-06  2018-12-11
2018-09-17  2018-09-30  2018-10-26  2018-10-31  2018-11-08  2018-12-02  2018-12-07  2018-12-12
2018-09-19  2018-10-08  2018-10-27  2018-11-01  2018-11-09  2018-12-03  2018-12-08  pay-sign-oper.log

[root@localhost pay-sign-oper]# ls 2018-09-13/
pay-sign-oper.2018-09-13.log

[root@localhost pay-sign-oper]# ls 2018-12-12/
pay-sign-oper.2018-12-12.log

比如現在開發同事想要刪除2018年11月08號之前的日誌, 現在就需要一個智慧指令碼, 用來一鍵實現這個需求.

指令碼內容如下:

[root@localhost pay-sign-oper]# cat date_log_delete.sh 
#!/bin/bash

echo -n "請輸入日期, 截止到該日期之前的日誌目錄接下來將要被刪除:"  
read  date1

date2=$(echo ${date1}|awk -F"-" '{print $1$2$3}')

cd `pwd`
for date3 in $(ls -l|grep "drwxr"|awk '{print $9}'|awk -F"-" '{print $1$2$3}')
do
   a=$(echo ${date3}|cut -c 1-4)
   b=$(echo ${date3}|cut -c 5-6)
   c=$(echo ${date3}|cut -c 7-8)
   date4=$(echo ${a}-${b}-${c})

     if [ ${date3} -lt ${date2} ];then
        rm -rf ${date4} && echo "deleted ${date4}"
     else
        echo "${date4} do not need to delete"
     fi
done

授予指令碼執行許可權
[root@localhost pay-sign-oper]# chmod 755 date_log_delete.sh
[root@localhost pay-sign-oper]# ll date_log_delete.sh
-rwxr-xr-x 1 root root 557 Dec 13 14:50 date_log_delete.sh

比如現在想要刪除2018年9月27號之前的日誌, 則指令碼執行後, 按照提示輸入:2018-09-27 即可實現:

[root@localhost pay-sign-oper]# sh date_log_delete.sh 
請輸入日期, 截止到該日期之前的日誌目錄接下來將要被刪除:2018-09-27
deleted 2018-09-13
deleted 2018-09-14
deleted 2018-09-15
deleted 2018-09-17
deleted 2018-09-19
deleted 2018-09-20
2018-09-27 do not need to delete
2018-09-29 do not need to delete
2018-09-30 do not need to delete
2018-10-08 do not need to delete
2018-10-11 do not need to delete
2018-10-24 do not need to delete
2018-10-25 do not need to delete
2018-10-26 do not need to delete
2018-10-27 do not need to delete
2018-10-28 do not need to delete
2018-10-29 do not need to delete
2018-10-30 do not need to delete
2018-10-31 do not need to delete
2018-11-01 do not need to delete
2018-11-02 do not need to delete
2018-11-06 do not need to delete
2018-11-07 do not need to delete
2018-11-08 do not need to delete
2018-11-09 do not need to delete
2018-11-14 do not need to delete
2018-11-15 do not need to delete
2018-11-30 do not need to delete
2018-12-02 do not need to delete
2018-12-03 do not need to delete
2018-12-04 do not need to delete
2018-12-05 do not need to delete
2018-12-06 do not need to delete
2018-12-07 do not need to delete
2018-12-08 do not need to delete
2018-12-09 do not need to delete
2018-12-10 do not need to delete
2018-12-11 do not need to delete
2018-12-12 do not need to delete

指令碼執行看, 檢視, 發現2018年9月27號之前的日誌和日誌目錄都被刪除了.
[root@localhost pay-sign-oper]# ls
2018-09-27  2018-10-11  2018-10-27  2018-10-31  2018-11-07  2018-11-15  2018-12-04  2018-12-08  2018-12-12
2018-09-29  2018-10-24  2018-10-28  2018-11-01  2018-11-08  2018-11-30  2018-12-05  2018-12-09  date_log_delete.sh
2018-09-30  2018-10-25  2018-10-29  2018-11-02  2018-11-09  2018-12-02  2018-12-06  2018-12-10  pay-sign-oper.log
2018-10-08  2018-10-26  2018-10-30  2018-11-06  2018-11-14  2018-12-03  2018-12-07  2018-12-11

以上指令碼看起來非常好用, 非常智慧! 此指令碼可以在任何這樣的日誌場景下使用. 下面針對指令碼中涉及到的一些shell小指令碼進行拆分說明:

1)
echo -n "請輸入日期, 截止到該日期之前的日誌目錄接下來將要被刪除:" 
read  date1
 
上面兩行指令碼內容用到了shell指令碼中的read引數.
read參數列示接收標準輸入(鍵盤)的輸入,或其他檔案描述符的輸入。
得到輸入內容後,read引數將該內容傳遞到一個標準變數中。
也就是指令碼執行後提示輸入的日期, 並將該日期傳給${date1}變數
 
2)
date2=$(echo ${date1}|awk -F"-" '{print $1$2$3}')
 
這一行指令碼內容是將輸入的日期的格式轉變成數字格式, 並傳給變數${date2}, 是為了和後面的變數${date3}做if語句中的大小判斷之用.
比如: 指令碼執行後提示輸入的內容是2018-09-27, 這個也就是變數${date1}的數值. 則變數${date}的值就是20180927.
[root@localhost pay-sign-oper]# echo 2018-09-27|awk -F"-" '{print $1$2$3}'
20180927
 
3)
cd `pwd`
 
這一行指令碼內容表示切換到當前目錄路徑下 (其實可以不寫這一行, 因為指令碼檔案就在當前目錄下)
 
4)
for date3 in $(ls -l|grep "drwxr"|awk '{print $9}'|awk -F"-" '{print $1$2$3}')
 
這一行指令碼內容表示在當前目錄下取日期目錄, 並將該日期目錄的格式轉變成數字形式, 並傳給變數${date3}, 是為了和${date2}做if語句中的大小判斷之用. 如下:
[root@localhost pay-sign-oper]# ls -l
total 136
drwxr-xr-x 2 root root 4096 Dec 13 14:56 2018-09-27
drwxr-xr-x 2 root root 4096 Dec 13 14:56 2018-09-29
drwxr-xr-x 2 root root 4096 Dec 13 14:55 2018-09-30
drwxr-xr-x 2 root root 4096 Dec 13 14:55 2018-10-08
...........
...........
drwxr-xr-x 2 root root 4096 Dec 13 12:40 2018-12-10
drwxr-xr-x 2 root root 4096 Dec 13 12:40 2018-12-11
drwxr-xr-x 2 root root 4096 Dec 13 12:40 2018-12-12
-rwxr-xr-x 1 root root  557 Dec 13 14:50 date_log_delete.sh
-rw-r--r-- 1 root root    0 Dec 13 12:40 pay-sign-oper.log


[root@localhost pay-sign-oper]# ls -l|grep "drwxr"|awk '{print $9}'
2018-09-27
2018-09-29
2018-09-30
2018-10-08
...........
...........
2018-12-10
2018-12-11
2018-12-12

[root@localhost pay-sign-oper]# ls -l|grep "drwxr"|awk '{print $9}'|awk -F"-" '{print $1$2$3}'
20180927
20180929
20180930
20181008
...........
...........
20181210
20181211
20181212
 
5)
a=$(echo ${date3}|cut -c 1-4)
b=$(echo ${date3}|cut -c 5-6)
c=$(echo ${date3}|cut -c 7-8)
 
這三行指令碼內容表示提取一個數字字串中的某幾位. a , b, c 三個變數分別表示取變數${date3}數字中的第1-4位, 第5-6位, 第7-8位.
比如變數${date3}的數值是20180927, 則:
[root@localhost pay-sign-oper]# echo 20180927|cut -c 1-4
2018
[root@localhost pay-sign-oper]# echo 20180927|cut -c 5-6
09
[root@localhost pay-sign-oper]# echo 20180927|cut -c 7-8
27
 
6) date4=$(echo ${a}-${b}-${c})
 
這一行指令碼內容表示將變數${date3}的數值拆分後再組成日期格式. 為了後面做if語句中的判斷結果後的日期目錄刪除操作.
 
7)
if [ ${date3} -lt ${date2} ];then
        rm -rf ${date4} && echo "deleted ${date4}"
     else
        echo "${date4} do not need to delete"
     fi
 
上面的指令碼內容表示if語句中判斷,:
當變數${date3}數值小於變數${date2}的數值時, 就刪除變數${date4}的日期目錄,並列印刪除資訊.
當變數${date3}數值大於等於變數${date2}的數值時, 就列印不要刪除的資訊.

相關文章