原文鏈接:
文章目錄
今日目標
- 熟悉awk的命令行模式基本語法結構
- 熟悉awk的相關內部變量
- 熟悉awk常用的打印函數print
- 能夠在awk中匹配正則表達式打印相關的行
一、awk介紹
1. awk概述
-
awk是一種編程語言,主要用於在linux/unix下對文本和數據進行處理,是linux/unix下的一個工具。數據可以來自標準輸入、一個或多個文件,或其它命令的輸出。
-
awk的處理文本和數據的方式:逐行掃描文件,默認從第一行到最後一行,尋找匹配的特定模式的行,並在這些行上進行你想要的操作。
-
awk分別代表其作者姓氏的第一個字母。因爲它的作者是三個人,分別是Alfred Aho、Brian Kernighan、Peter Weinberger。
-
gawk是awk的GNU版本,它提供了Bell實驗室和GNU的一些擴展。
-
下面介紹的awk是以GNU的gawk爲例的,在linux系統中已把awk鏈接到gawk,所以下面全部以awk進行介紹。
2. awk能幹啥?
- awk用來處理文件和數據的,是類unix下的一個工具,也是一種編程語言
- 可以用來統計數據,比如網站的訪問量,訪問的IP量等等
- 支持條件判斷,支持for和while循環
二、awk使用方式
1. 命令行模式使用
(一) 語法結構
awk 選項 '命令部分' 文件名
特別說明:
引用shell變量需用雙引號引起
(二)常用選項介紹
- -F 定義字段分割符號,默認的分隔符是空格
- -v 定義變量並賦值
(三) '命名部分說明’
- 正則表達式,地址定位
'/root/{awk語句}' sed中: '/root/p'
'NR==1,NR==5{awk語句}' sed中: '1,5p'
'/^root/,/^ftp/{awk語句}' sed中:'/^root/,/^ftp/p'
- {awk語句1**;awk語句2;**…}
'{print $0;print $1}' sed中:'p'
'NR==5{print $0}' sed中:'5p'
注:awk命令語句間用分號間隔
- BEGIN…END…
'BEGIN{awk語句};{處理中};END{awk語句}'
'BEGIN{awk語句};{處理中}'
'{處理中};END{awk語句}'
2. 腳本模式使用
(一) 腳本編寫
#!/bin/awk -f 定義魔法字符
以下是awk引號裏的命令清單,不要用引號保護命令,多個命令用分號間隔
BEGIN{FS=":"}
NR==1,NR==3{print $1"\t"$NF}
...
(二) 腳本執行
方法1:
awk 選項 -f awk的腳本文件 要處理的文本文件
awk -f awk.sh filename
sed -f sed.sh -i filename
方法2:
./awk的腳本文件(或者絕對路徑) 要處理的文本文件
./awk.sh filename
./sed.sh filename
三、 awk內部相關變量
變量 | 變量說明 | 備註 |
---|---|---|
$0 | 當前處理行的所有記錄 | |
$1,$2,$3…$n | 文件中每行以間隔符號分割的不同字段 | awk -F: ‘{print $1,$3}’ |
NF | 當前記錄的字段數(列數) | awk -F: ‘{print NF}’ |
$NF | 最後一列 | $(NF-1)表示倒數第二列 |
FNR/NR | 行號 | |
FS | 定義間隔符 | ‘BEGIN{FS=":"};{print $1,$3}’ |
OFS | 定義輸出字段分隔符,默認空格 | ‘BEGIN{OFS="\t"};print $1,$3}’ |
RS | 輸入記錄分割符,默認換行 | ‘BEGIN{RS="\t"};{print $0}’ |
ORS | 輸出記錄分割符,默認換行 | ‘BEGIN{ORS="\n\n"};{print $1,$3}’ |
FILENAME | 當前輸入的文件名 |
1、常用內置變量舉例
# head /etc/passwd > 1.txt
# awk -F: '{print $1,$(NF-1)}' 1.txt
# awk -F: '{print $1,$(NF-1),$NF,NF}' 1.txt
# awk '/root/{print $0}' 1.txt
# awk '/root/' 1.txt
# awk -F: '/root/{print $1,$NF}' 1.txt
root /bin/bash
# awk -F: '/root/{print $0}' 1.txt
root:x:0:0:root:/root:/bin/bash
# awk 'NR==1,NR==5' 1.txt
# awk 'NR==1,NR==5{print $0}' 1.txt
# awk 'NR==1,NR==5;/^root/{print $0}' 1.txt
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
2、內置變量分隔符舉例
FS和OFS:
# awk 'BEGIN{FS=":"};/^root/,/^lp/{print $1,$NF}' 1.txt
# awk -F: 'BEGIN{OFS="\t\t"};/^root/,/^lp/{print $1,$NF}' 1.txt
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
# awk -F: 'BEGIN{OFS="@@@"};/^root/,/^lp/{print $1,$NF}' 1.txt
root@@@/bin/bash
bin@@@/sbin/nologin
daemon@@@/sbin/nologin
adm@@@/sbin/nologin
lp@@@/sbin/nologin
[root@server shell07]#
RS和ORS:
修改源文件前2行增加製表符和內容:
vim 1.txt
root:x:0:0:root:/root:/bin/bash hello world
bin:x:1:1:bin:/bin:/sbin/nologin test1 test2
# awk 'BEGIN{RS="\t"};{print $0}' 1.txt
# awk 'BEGIN{ORS="\t"};{print $0}' 1.txt
四、 awk工作原理
awk -F: '{print $1,$3,$4}' /etc/passwd
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-TfGC0nZB-1585189232027)(images/awk-working-principle.jpg)]
-
awk使用一行作爲輸入,並將這一行賦給內部變量$0,每一行也可稱爲一個記錄,以換行符(RS)結束
-
每行被間隔符**😗*(默認爲空格或製表符)分解成字段(或域),每個字段存儲在已編號的變量中,從$1開始
問:awk如何知道用空格來分隔字段的呢?
答:因爲有一個內部變量FS來確定字段分隔符。初始時,FS賦爲空格
-
awk使用print函數打印字段,打印出來的字段會以空格分隔,因爲$1,$3之間有一個逗號。逗號比較特殊,它映射爲另一個內部變量,稱爲輸出字段分隔符OFS,OFS默認爲空格
-
awk處理完一行後,將從文件中獲取另一行,並將其存儲在$0中,覆蓋原來的內容,然後將新的字符串分隔成字段並進行處理。該過程將持續到所有行處理完畢
五、awk使用進階
1. 格式化輸出print
和printf
print函數 類似echo "hello world"
# date |awk '{print "Month: "$2 "\nYear: "$NF}'
# awk -F: '{print "username is: " $1 "\t uid is: "$3}' /etc/passwd
printf函數 類似echo -n
# awk -F: '{printf "%-15s %-10s %-15s\n", $1,$2,$3}' /etc/passwd
# awk -F: '{printf "|%15s| %10s| %15s|\n", $1,$2,$3}' /etc/passwd
# awk -F: '{printf "|%-15s| %-10s| %-15s|\n", $1,$2,$3}' /etc/passwd
awk 'BEGIN{FS=":"};{printf "%-15s %-15s %-15s\n",$1,$6,$NF}' a.txt
%s 字符類型 strings %-20s
%d 數值類型
佔15字符
- 表示左對齊,默認是右對齊
printf默認不會在行尾自動換行,加\n
2. awk變量定義
# awk -v NUM=3 -F: '{ print $NUM }' /etc/passwd
# awk -v NUM=3 -F: '{ print NUM }' /etc/passwd
# awk -v num=1 'BEGIN{print num}'
1
# awk -v num=1 'BEGIN{print $num}'
注意:
awk中調用定義的變量不需要加$
3. awk中BEGIN…END使用
①BEGIN:表示在程序開始前執行
②END : 表示所有文件處理完後執行
③用法:'BEGIN{開始處理之前};{處理中};END{處理結束後}'
(一) 舉例說明1
打印最後一列和倒數第二列(登錄shell和家目錄)
awk -F: 'BEGIN{ print "Login_shell\t\tLogin_home\n*******************"};{print $NF"\t\t"$(NF-1)};END{print "************************"}' 1.txt
awk 'BEGIN{ FS=":";print "Login_shell\tLogin_home\n*******************"};{print $NF"\t"$(NF-1)};END{print "************************"}' 1.txt
Login_shell Login_home
************************
/bin/bash /root
/sbin/nologin /bin
/sbin/nologin /sbin
/sbin/nologin /var/adm
/sbin/nologin /var/spool/lpd
/bin/bash /home/redhat
/bin/bash /home/user01
/sbin/nologin /var/named
/bin/bash /home/u01
/bin/bash /home/YUNWEI
************************************
(二) 舉例說明2
打印/etc/passwd裏的用戶名、家目錄及登錄shell
u_name h_dir shell
***************************
***************************
awk -F: 'BEGIN{OFS="\t\t";print"u_name\t\th_dir\t\tshell\n***************************"};{printf "%-20s %-20s %-20s\n",$1,$(NF-1),$NF};END{print "****************************"}' 1.txt
# awk -F: 'BEGIN{print "u_name\t\th_dir\t\tshell" RS "*****************"} {printf "%-15s %-20s %-20s\n",$1,$(NF-1),$NF}END{print "***************************"}' /etc/passwd
格式化輸出:
echo print
echo -n printf
{printf "%-15s %-20s %-20s\n",$1,$(NF-1),$NF}
4. awk和正則的綜合運用
運算符 | 說明 |
---|---|
== | 等於 |
!= | 不等於 |
> | 大於 |
< | 小於 |
>= | 大於等於 |
<= | 小於等於 |
~ | 匹配 |
!~ | 不匹配 |
! | 邏輯非 |
&& | 邏輯與 |
|| | 邏輯或 |
(一) 舉例說明
從第一行開始匹配到以lp開頭行
awk -F: 'NR==1,/^lp/{print $0 }' /etc/passwd
從第一行到第5行
awk -F: 'NR==1,NR==5{print $0 }' /etc/passwd
從以lp開頭的行匹配到第10行
awk -F: '/^lp/,NR==10{print $0 }' /etc/passwd
從以root開頭的行匹配到以lp開頭的行
awk -F: '/^root/,/^lp/{print $0}' /etc/passwd
打印以root開頭或者以lp開頭的行
awk -F: '/^root/ || /^lp/{print $0}' /etc/passwd
awk -F: '/^root/;/^lp/{print $0}' passwd
顯示5-10行
awk -F':' 'NR>=5 && NR<=10 {print $0}' /etc/passwd
awk -F: 'NR<=10 && NR>=5 {print $0}' /etc/passwd
打印30-39行以bash結尾的內容:
[root@localhost ~]# awk 'NR>=30 && NR<=39 && $0 ~ /bash$/{print $0}' passwd
zhangjm:x:500:500:root:/home/zhangjm:/bin/bash
[root@localhost ~]# awk 'NR>=3 && NR<=8 && /nologin$/' 1.txt
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
打印文件中1-5並且以root開頭的行
[root@localhost ~]# awk 'NR>=1 && NR<=5 && $0 ~ /^root/{print $0}' 1.txt
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# awk 'NR>=1 && NR<=5 && $0 !~ /^root/{print $0}' 1.txt
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
理解;號和||的含義:
[root@localhost ~]# awk 'NR>=3 && NR<=8 || /bash$/' 1.txt
[root@localhost ~]# awk 'NR>=3 && NR<=8;/bash$/' 1.txt
打印IP地址
# ifconfig eth0|awk 'NR>1 {print $2}'|awk -F':' 'NR<2 {print $2}'
# ifconfig eth0|grep Bcast|awk -F':' '{print $2}'|awk '{print $1}'
# ifconfig eth0|grep Bcast|awk '{print $2}'|awk -F: '{print $2}'
# ifconfig eth0|awk NR==2|awk -F '[ :]+' '{print $4RS$6RS$8}'
# ifconfig eth0|awk -F"[ :]+" '/inet addr:/{print $4}'
4. 課堂練習
- 顯示可以登錄操作系統的用戶所有信息 從第7列匹配以bash結尾,輸出整行(當前行所有的列)
[root@localhost ~] awk '/bash$/{print $0}' /etc/passwd
[root@localhost ~] awk '/bash$/{print $0}' /etc/passwd
[root@localhost ~] awk '/bash$/' /etc/passwd
[root@localhost ~] awk -F: '$7 ~ /bash/' /etc/passwd
[root@localhost ~] awk -F: '$NF ~ /bash/' /etc/passwd
[root@localhost ~] awk -F: '$0 ~ /bash/' /etc/passwd
[root@localhost ~] awk -F: '$0 ~ /\/bin\/bash/' /etc/passwd
- 顯示可以登錄系統的用戶名
# awk -F: '$0 ~ /\/bin\/bash/{print $1}' /etc/passwd
- 打印出系統中普通用戶的UID和用戶名
500 stu1
501 yunwei
502 user01
503 user02
504 user03
# awk -F: 'BEGIN{print "UID\tUSERNAME"} {if($3>=500 && $3 !=65534 ) {print $3"\t"$1} }' /etc/passwdUID USERNAME
# awk -F: '{if($3 >= 500 && $3 != 65534) print $1,$3}' a.txt
redhat 508
user01 509
u01 510
YUNWEI 511
5. awk的腳本編程
(一) 流程控制語句
① if結構
if語句:
if [ xxx ];then
xxx
fi
格式:
awk 選項 '正則,地址定位{awk語句}' 文件名
{ if(表達式){語句1;語句2;...}}
#$3爲uid
awk -F: '{if($3>=500 && $3<=60000) {print $1,$3} }' passwd
# awk -F: '{if($3==0) {print $1"是管理員"} }' passwd
root是管理員
# awk 'BEGIN{if('$(id -u)'0) {print "admin"} }'
admin
② if…else結構
if...else語句:
if [ xxx ];then
xxxxx
else
xxx
fi
格式:
{if(表達式){語句;語句;...}else{語句;語句;...}}
awk -F: '{ if($3>=500 && $3 != 65534) {print $1"是普通用戶"} else {print $1,"不是普通用戶"}}' passwd
awk 'BEGIN{if( '$(id -u)'>=500 && '$(id -u)' !=65534 ) {print "是普通用戶"} else {print "不是普通用戶"}}'
③ if…elif…else結構
if [xxxx];then
xxxx
elif [xxx];then
xxx
....
else
...
fi
if...else if...else語句:
格式:
{ if(表達式1){語句;語句;...}else if(表達式2){語句;語句;...}else if(表達式3){語句;語句;...}else{語句;語句;...}}
awk -F: '{ if($3==0) {print $1,":是管理員"} else if($3>=1 && $3<=499 || $3==65534 ) {print $1,":是系統用戶"} else {print $1,":是普通用戶"}}'
awk -F: '{ if($3==0) {i++} else if($3>=1 && $3<=499 || $3==65534 ) {j++} else {k++}};END{print "管理員個數爲:"i "\n系統用戶個數爲:"j"\n普通用戶的個數爲:"k }'
# awk -F: '{if($3==0) {print $1,"is admin"} else if($3>=1 && $3<=499 || $3==65534) {print $1,"is sys users"} else {print $1,"is general user"} }' 1.txt
awk -F: '{ if($3==0) {print $1":管理員"} else if($3>=1 && $3<500 || $3==65534 ) {print $1":是系統用戶"} else {print $1":是普通用戶"}}' /etc/passwd
awk -F: '{if($3==0) {i++} else if($3>=1 && $3<500 || $3==65534){j++} else {k++}};END{print "管理員個數爲:" i RS "系統用戶個數爲:"j RS "普通用戶的個數爲:"k }' /etc/passwd
數爲:1
系統用戶個數爲:29
普通用戶的個數爲:1
# awk -F: '{ if($3==0) {print $1":是管理員"} else if($3>=500 && $3!=65534) {print $1":是普通用戶"} else {print $1":是系統用戶"}}' passwd
awk -F: '{if($3==0){i++} else if($3>=500){k++} else{j++}} END{print i; print k; print j}' /etc/passwd
awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print "管理員個數: "i; print "普通用個數: "k; print "系統用戶: "j}' /etc/passwd
如果是普通用戶打印默認shell,如果是系統用戶打印用戶名
# awk -F: '{if($3>=1 && $3<500 || $3 65534) {print $1} else if($3>=500 && $3<=60000 ) {print $NF} }' /etc/passwd
(二) 循環語句
① for循環
打印1~5
for ((i=1;i<=5;i++));do echo $i;done
# awk 'BEGIN { for(i=1;i<=5;i++) {print i} }'
打印1~10中的奇數
# for ((i=1;i<=10;i+=2));do echo $i;done|awk '{sum+=$0};END{print sum}'
# awk 'BEGIN{ for(i=1;i<=10;i+=2) {print i} }'
# awk 'BEGIN{ for(i=1;i<=10;i+=2) print i }'
計算1-5的和
# awk 'BEGIN{sum=0;for(i=1;i<=5;i++) sum+=i;print sum}'
# awk 'BEGIN{for(i=1;i<=5;i++) (sum+=i);{print sum}}'
# awk 'BEGIN{for(i=1;i<=5;i++) (sum+=i);print sum}'
② while循環
打印1-5
# i=1;while (($i<=5));do echo $i;let i++;done
# awk 'BEGIN { i=1;while(i<=5) {print i;i++} }'
打印1~10中的奇數
# awk 'BEGIN{i=1;while(i<=10) {print i;i+=2} }'
計算1-5的和
# awk 'BEGIN{i=1;sum=0;while(i<=5) {sum+=i;i++}; print sum }'
# awk 'BEGIN {i=1;while(i<=5) {(sum+=i) i++};print sum }'
③ 嵌套循環
嵌套循環:
#!/bin/bash
for ((y=1;y<=5;y++))
do
for ((x=1;x<=$y;x++))
do
echo -n $x
done
echo
done
awk 'BEGIN{ for(y=1;y<=5;y++) {for(x=1;x<=y;x++) {printf x} ;print } }'
# awk 'BEGIN { for(y=1;y<=5;y++) { for(x=1;x<=y;x++) {printf x};print} }'
1
12
123
1234
12345
# awk 'BEGIN{ y=1;while(y<=5) { for(x=1;x<=y;x++) {printf x};y++;print}}'
1
12
123
1234
12345
嘗試用三種方法打印99口訣表:
#awk 'BEGIN{for(y=1;y<=9;y++) { for(x=1;x<=y;x++) {printf x"*"y"="x*y"\t"};print} }'
#awk 'BEGIN{for(y=1;y<=9;y++) { for(x=1;x<=y;x++) printf x"*"y"="x*y"\t";print} }'
#awk 'BEGIN{i=1;while(i<=9){for(j=1;j<=i;j++) {printf j"*"i"="j*i"\t"};print;i++ }}'
#awk 'BEGIN{for(i=1;i<=9;i++){j=1;while(j<=i) {printf j"*"i"="i*j"\t";j++};print}}'
循環的控制:
break 條件滿足的時候中斷循環
continue 條件滿足的時候跳過循環
# awk 'BEGIN{for(i=1;i<=5;i++) {if(i==3) break;print i} }'
1
2
# awk 'BEGIN{for(i=1;i<=5;i++){if(i==3) continue;print i}}'
1
2
4
5
6. awk算數運算
+ - * / %(模) ^(冪2^3)
可以在模式中執行計算,awk都將按浮點數方式執行算術運算
# awk 'BEGIN{print 1+1}'
# awk 'BEGIN{print 1**1}'
# awk 'BEGIN{print 2**3}'
# awk 'BEGIN{print 2/3}'
六、awk統計案例
1、統計系統中各種類型的shell
# awk -F: '{ shells[$NF]++ };END{for (i in shells) {print i,shells[i]} }' /etc/passwd
# 涉及關聯數組
books[linux]++
books[linux]=1
shells[/bin/bash]++
shells[/sbin/nologin]++
/bin/bash 5
/sbin/nologin 6
shells[/bin/bash]++ a
shells[/sbin/nologin]++ b
shells[/sbin/shutdown]++ c
books[linux]++
books[php]++
2、統計網站訪問狀態
# ss -antp|grep 80|awk '{states[$1]++};END{for(i in states){print i,states[i]}}'
TIME_WAIT 578
ESTABLISHED 1
LISTEN 1
# ss -an |grep :80 |awk '{states[$2]++};END{for(i in states){print i,states[i]}}'
LISTEN 1
ESTAB 5
TIME-WAIT 25
# ss -an |grep :80 |awk '{states[$2]++};END{for(i in states){print i,states[i]}}' |sort -k2 -rn
TIME-WAIT 18
ESTAB 8
LISTEN 1
3、統計訪問網站的每個IP的數量
# netstat -ant |grep :80 |awk -F: '{ip_count[$8]++};END{for(i in ip_count){print i,ip_count[i]} }' |sort
# ss -an |grep :80 |awk -F":" '!/LISTEN/{ip_count[$(NF-1)]++};END{for(i in ip_count){print i,ip_count[i]}}' |sort -k2 -rn |head
4、統計網站日誌中PV量
統計Apache/Nginx日誌中某一天的PV量 <統計日誌>
# grep '16/Mar/2020' mysqladmin.cc-access_log |wc -l
14519
統計Apache/Nginx日誌中某一天不同IP的訪問量 <統計日誌>
# grep '16/Mar/2020' mysqladmin.cc-access_log |awk '{ips[$1]++};END{for(i in ips){print i,ips[i]} }' |sort -k2 -rn |head
# grep '16/Mar/2020' access.log |awk '{ips[$1]++};END{for(i in ips){print i,ips[i]} }' |awk '$2>100' |sort -k2 -rn
名詞解釋:
網站瀏覽量(PV)
名詞:PV=PageView (網站瀏覽量)
說明:指頁面的瀏覽次數,用以衡量網站用戶訪問的網頁數量。多次打開同一頁面則瀏覽量累計。用戶每打開一個頁面便記錄1次PV。
名詞:VV = Visit View(訪問次數)
說明:從訪客來到您網站到最終關閉網站的所有頁面離開,計爲1次訪問。若訪客連續30分鐘沒有新開和刷新頁面,或者訪客關閉了瀏覽器,則被計算爲本次訪問結束。
獨立訪客(UV)
名詞:UV= Unique Visitor(獨立訪客數)
說明:1天內相同的訪客多次訪問您的網站只計算1個UV。
獨立IP(IP)
名詞:IP=獨立IP數
說明:指1天內使用不同IP地址的用戶訪問網站的數量。同一IP無論訪問了幾個頁面,獨立IP數均爲1
七、企業實戰案例
1. 任務/背景
web服務器集羣中總共有9臺機器,上面部署的是Apache服務。由於業務不斷增長,每天每臺機器上都會產生大量的訪問日誌,現需要將每臺web服務器上的apache訪問日誌保留最近3天的,3天以前的日誌轉儲到一臺專門的日誌服務器上,已做後續分析。如何實現每臺服務器上只保留3天以內的日誌?
2. 具體要求
- 每臺web服務器的日誌對應日誌服務器相應的目錄裏。如:web1——>web1.log(在日誌服務器上)
- 每臺web服務器上保留最近3天的訪問日誌,3天以前的日誌每天凌晨5:03分轉儲到日誌服務器
- 如果腳本轉儲失敗,運維人員需要通過跳板機的菜單選擇手動清理日誌
3. 涉及知識點
- shell的基本語法結構
- 文件同步rsync
- 文件查找命令find
- 計劃任務crontab
- apache日誌切割
- 其他
apache日誌每天進行輪轉
vim /usr/loacal/apache2/conf/extar/httpd-vhosts.conf
說明:
1.rotatelogs程序是apache自帶的一個日誌切割工具。-l參數表示使用本地系統時間爲標準切割,而不是GMT時區時間
2./usr/local/apache2/logs/access_log-%Y%m%d 86400 用來指定文件的位置和名稱,其中86400用來指定分割時間,默認點位爲s,也就是24小時;
log-server上搭建rsync:ip 10.1.1.2
cat /etc/rsyncd.conf
[web1]
path = /web1/logs
uid = root
gid = root
read only = false
[web2]
path = /web2/logs
uid = root
gid = root
read only = false
echo rsync --daemon >> /etc/rc.local
web服務器上定義日誌清理腳本
#!/bin/bash
# clean log
clean_log(){
remote_log_server=10.1.1.2
server=$1
log_dir=/usr/local/apaches/logs
log_tmp_dir=/tmp/log
host=`ifconfig eth0 | sed -n '2p' | awk -F'[ :]+' '{print $4}'`
[ ! -d $log_tmp_dir ] && mkdir -p $log_tmp_dir
cd $log_dir
find ./-daystart -mtime +3 -exec tar -uf %log_tmp_dir/`echo $host`_$(date+%F).tar{}\;
find ./-daystart -mtime +3 -delete
cd $log_tmp_dir
rsync -a ./$remote_log_server::$server && find./-daystart -mtime +1 -delete
}
#!/bin/bash
# jumper server
trap '' 1 2 3
menu1(){
cat <<-END
Please select the operate type for web1:
1.clean_apache_log
2.reload_apache_service
3.test_apache_service
4.remote_login
END
}
menu2(){
cat <<-END
Welcome to use Jumper-server, Please select the operation host:
1.DB1-Master
2.DB2-Slave
3.Web1
4.Web2
5.exit
END
}
push_pubkey(){
ip=$1
#判斷公鑰文件是否存在,沒有則生成公鑰
[ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -P ** -f ~/.ssh/id_rsa&>/dev/null
sudo rpm -q expect &>/dev/null
test $? -ne 0 && sudo yum -y install expect
#將跳板機上指定用戶的公鑰推送到指定的服務器上
/usr/bin/expect<<-EOF
spawn ssh-copy-id -i root@$ip
expect{
"yes/no" {send "yes\r";exp_contine}
"password:"{send "11111\n"}
}
expect eof
EOF
}
while true
do
menu2
read -p "請輸入你要操作的主機:" host
case $host in
1)
ssh root@10.1.1.2
;;
2)
ssh root@10.1.1.3
;;
3)
clear
menu1
read -p "請輸入你的操作類型" types
case $types in
1)
ssh root@10.1.1.1 clean_log web1
test $? -eq 0 && echo "日誌清理完畢..."
;;
2)
service apache reload
;;
3)
wget http://10.1.1.1&>/dev/null
test $? -eq 0 && echo "該web服務運行正常" || echo "該web服務無法訪問,請檢查..."
;;
4)
ssh root@10.1.1.1
;;
*)
:
;;
esac
;;
5)
exit
;;
*)
clear
echo "輸入錯誤,請重新輸入..."
;;
esac
done