8一、題目要求 : 監控磁盤php
阿里雲的機器,今天收到客服來的電話,說服務器的磁盤io很重。因而登陸到服務器查看,並無發現問題,因此懷疑是間歇性地。正要考慮寫個腳本的時候,幸運的抓到了一個線索,形成磁盤io很高的幕後黑手是mysql。此時去show processlist,但未發現有問題的隊列。原來只是一瞬間。只好繼續來寫腳本,思路是,每5s檢測一次磁盤io,當發現問題去查詢mysql的processlist。java
【核心要點】python
iostat -xd 1 5 ,主要看%util ;-xd :只查看磁盤信息。mysql
#!/bin/bash #這個腳本用來監控磁盤IO #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-12 if ! while iostat &>/dev/null then yum install -y sysstat fi while : do t=`date +%T` iostat -xd 1 5 |grep '^sda'> /tmp/io.log sum=`awk '{sum=sum+$NF} END {print sum}' /tmp/io.log` a=`echo "scale=2;$sum/5"|bc` b=`echo $a|cut -d . -f 1` if [ $b -gt 90 ] then mysql -uroot -pxxxx -e "show processlist" > mysql_$t.log fi sleep 1 done
實例 :linux
查看磁盤的讀寫速度。%util越大,說明磁盤越忙。ios
查看平均磁盤讀寫速率git
查看磁盤sda的讀寫速度,查看最後一列。github
將磁盤sda的讀寫速度寫入到/tmp/io.log。取最後一列使用「$NF」,顯示磁盤的讀寫速度是0.02sql
修改磁盤讀寫速度,用於測試。shell
6.92除以5,求磁盤平均讀寫速度。
取一位整數
執行腳本,查看結果
注意 :
yum install -y sysstat #安裝查看io的命令軟件包
if ! while iostat &>/dev/null #查看iostat有沒有安裝,若是沒有,執行下面的任務。
t=`date +%T` #顯示當前系統時間
iostat -xd 1 5 |grep '^sda'> /tmp/io.log #將磁盤sda的讀寫速度寫入到/tmp/io.log。
sum=`awk '{sum=sum+$NF} END {print sum}' /tmp/io.log` #將磁盤sda的讀寫速度寫入到/tmp/io.log。取最後一列使用「$NF」,寫入到/tmp/io.log。
a=`echo "scale=2;$sum/5"|bc` #除以5,保留2位數字
b=`echo $a|cut -d . -f 1` #取一位整數
if [ $b -gt 90 ] #查看gt的值是否大於90
mysql -uroot -pxxxx -e "show processlist" > mysql_$t.log #若是當發現問題去查詢mysql的processlist。,並寫入到mysql_$t.log日誌裏面
8二、題目要求 : 查看tomcat日誌
寫一個截取tomcat catalina.out日誌的腳本 tomcat實例t1-t4
# find /opt/TOM/ -name catalina.out /opt/TOM/t1/logs/catalina.out /opt/TOM/t3/logs/catalina.out /opt/TOM/t4/logs/catalina.out /opt/TOM/t2/logs/catalina.out
要求:
Oct 29, 2018 01:52:24 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-bio-8080"] Oct 29, 2018 01:52:24 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["ajp-bio-8009"] Oct 29, 2018 01:52:24 PM org.apache.catalina.startup.Catalina start INFO: Server startup in 2102 ms
【核心要點】
#!/bin/bash #這個腳本用來查看Tomcat日誌 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-12 LANG=en logfile="/opt/TOM/$1/logs/catalina.out" #將當天的英文月、數字日期、數字年做爲變量賦值給d_mdy d_mdy=`date "+%b %d, %Y"` #判斷參數個數 if [ $# -ne 2 ] && [ $# -ne 3 ] then echo "你提供的參數個數不對,請提供2個或者3個參數。例:sh $0 t1 08:01:00 14:00:00" exit 1 fi #判斷第一個參數是否符合要求 if ! echo $1|grep -qE '^t1$|^t2$|^t3$|^t4$' then echo "第一個參數必須是t一、t二、t3或t4" exit 1 fi #判斷時間有效性 judge_time() { date -d "$1" +%s &>/dev/null if [ $? -ne 0 ] then echo "你提供的時間$1格式不正確" exit 1 fi } #將24小時制時間轉換爲12小時 tr_24_12() { date -d "$1" +%r } #判斷提供的時間點是否在日誌中出現 judge_time_in_log() { if ! grep -q "$d_mdy $(tr_24_12 $1)" $logfile then echo "你提供的時間$1在日誌$logfile中未曾出現,請換一個時間點" exit 1 fi } #判斷第2個參數是否合法 judge_time $2 #判斷起始時間點是否出如今日誌裏 judge_time_in_log $2 #若是提供第3個參數 if [ $# -eq 3 ] then #判斷第3個參數是否合法 judge_time $3 #判斷起始時間是否早於結束時間 t1=`date -d "$2" +%s` t2=`date -d "$3" +%s` if [ $t2 -lt $t1 ] then echo "你提供的時間$2比$3要晚,應該把早的時間放到前面" exit fi #判斷提供的結束時間點是否出如今日誌中 judge_time_in_log $3 fi #取起始時間所在行行號 begin_n=`grep -n "$d_mdy $(tr_24_12 $2)" $logfile|head -1|awk -F ':' '{print $1}'` #取結束時間所在行行號,並用sed截取日誌內容 if [ $# -eq 3 ] then n=`grep -n "$d_mdy $(tr_24_12 $3)" $logfile|tail -1|awk -F ':' '{print $1}'` #結束日期所在行的下一行纔是日誌的內容 end_n=$[$n+1] sed -n "$begin_n,$end_n"p $logfile else sed -n "$begin_n,$"p $logfile fi
實例 :
查看系統時間,是否和tomcat日誌裏面的時間同樣。
將24小時時間制轉換成12小時時間制,和Tomcat日誌的時間格式同樣,便於觀察。
執行腳本,查看結果
注意 「:
date -d "$1" +%s &>/dev/null #將用戶輸入的參數,寫入到/dev/null 中,-d測試,$1表示用戶輸入的時間
if [ $# -ne 2 ] && [ $# -ne 3 ] #提供的參數 不是2,也不是3時。提示用戶。
if ! grep -q "$d_mdy $(tr_24_12 $1)" $logfile #將24小時時間制轉換成12小時時間制,grep -p檢查時間格式是否是和日誌中的同樣。
8三、題目要求 : 打印城市名字
寫一個腳本讓用戶輸入多個城市的名字(能夠是中文),要求很多於5個,而後把這些城市存到一個數組裏,最後用for循環把它們打印出來。
【核心要點】
賦值數組 : arry=(1 2 a b c)
打印數組 : echo ${arry[@]}
#!/bin/bash #這個腳本用來打印城市名字 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-12 read -p "輸入很多於5個城市的名字,用空格分隔開。" name n=`echo $name|awk '{print NF}'` if [ $n -lt 5 ] then echo "請輸入至少5個城市的名字." exit fi city=($name) for i in `seq 0 $[${#city[@]}-1]` do echo ${city[$i]} done
實例 :
打印數組
查看數組的循環,發現是從0開始的。
數組的賦值 ;打印數組的值 ; 統計數組的個數 ;針對個別元素。
執行腳本,查看結果。
注意 :
n=`echo $name|awk '{print NF}'` #名字之間,用空格隔開。
if [ $n -lt 5 ] #$n的值小於5,
for i in `seq 0 $[${#city[@]}-1]` #打印用戶輸入的城市名,由於數組的循環是從0開始的,因此要減一。
8四、題目要求 : 代碼上線
需求背景是: 一個業務,有3臺服務器(A,B,C)作負載均衡,因爲規模過小目前並未使用專業的自動化運維工具。有新的需求時,開發同事改完代碼會把變動上傳到其中一臺服務器A上。可是其餘2臺服務器也須要作相同變動。
寫一個shell腳本,把A服務器上的變動代碼同步到B和C上。 其中,你須要考慮到不須要同步的目錄(假若有tmp、upload、logs、caches)
rsync同步
密鑰認證或者expect腳本
#!/bin/bash #這個腳本用來代碼上線 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-12 dir=/data/wwwroot/www.aaa.com B_IP=1.1.1.1 C_IP=2.2.2.2 rs() { rsync -azP --exclude="logs" \ --exclude="tmp" --exclude="upload" \ --exclude="caches" $dir/ $1:$dir/ } read -p "該腳本將會把本機的$dir下的文件同步到$B_IP和$C_IP上,是否要繼續?y|n" c case $c in y|Y) rs B_IP rs C_IP ;; n|N) exit ;; *) echo "你只能輸入y或者n." ;; esac
注意 :
dir=/data/wwwroot/www.aaa.com #假如a ,b,c機器的變動代碼須要同步的目錄都是同樣。
rsync -azP --exclude="logs" \
--exclude="tmp" --exclude="upload" \
--exclude="caches" $dir/ $1:$dir/ #把A服務器上的變動代碼同步到B和C上,排除的目錄tmp、upload、logs、caches。 $dir/ $1:$dir/表示$dir同步到b機器下的$dir目錄下,$1是b機器的IP
需求背景:
須要統計網站的併發量,並繪圖。 說明: 只須要寫出shell腳本便可,不用關心zabbix配置。
假設日誌路徑 /data/logs/www.aaa.com_access.log
日誌格式以下:
112.107.15.12 - [07/Nov/2018:09:59:01 +0800] www.aaa.com "/api/live.php" 200"-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)"
【核心要點】
查看日誌中1秒內的日誌數量,即併發數(每秒請求多少次)
#!/bin/bash #這個腳本用來計算網站併發量 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-12 LANG=en t=`date -d "-1 second" +%d/%b/%Y:%` log=/data/logs/www.aaa.com_access.log tail -1000 $log |grep -c "$t"
實例 :
獲取上一秒的時間。%b : 做用是顯示月份。
獲取上一秒的時間,與日誌顯示的時間一致。
執行腳本,查看結果
注意 :
t=`date -d "-1 second" +%d/%b/%Y:%` # 求上一秒的日誌時間
log=/data/logs/www.aaa.com_access.log #訪問日誌,經過訪問日誌,計算網站的併發量
tail -1000 $log |grep -c "$t" #統計最後一千條併發量日誌,並截取到日誌時間
8六、題目要求 : 關閉服務
在centos6系統裏,咱們可使用ntsysv關閉不須要開機啓動的服務,固然也可使用chkconfig工具來實現。
寫一個shell腳本,用chkconfig工具把不經常使用的服務關閉。腳本須要寫成交互式的,須要咱們給它提供關閉的服務名字。
chkconfig --list
#!/bin/bash #這個腳本用來關閉服務 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-14 LANG=en while : do chkconfig --list 2>/dev/null|grep '3:on' |awk '{print $1}' > /tmp/on_sev.txt echo -e "\033[32m系統裏開啓了這些服務: \033[0m" cat /tmp/on_sev.txt echo read -p "Please select a service from this list: " s if ! grep -qw "$s" /tmp/on_sev.txt then echo -e "\033[31m你提供的服務名並未開啓.\033[0m" continue fi chkconfig $s off break done
實例 :
查看服務列表
列出開啓的服務,並顯示在一列。
給字體添加顏色
執行腳本,查看結果
注意 :
chkconfig --list 2>/dev/null|grep '3:on' |awk '{print $1}' > /tmp/on_sev.txt #列出全部的on服務,
echo -e "\033[32m系統裏開啓了這些服務: \033[0m" #
if ! grep -qw "$s" /tmp/on_sev.txt #查看$s,是否在/tmp/on_sev.txt ,不存在,就提示用戶。
chkconfig $s off #關閉不須要開機啓動的$s服務。
8七、題目要求 : 完全關閉tomcat服務
在生產環境中,常常遇到tomcat沒法完全關閉,也就是說用tomcat自帶shutdown.sh腳本沒法將java進程徹底關掉。因此,須要藉助shell腳本,將進程殺死,而後再啓動。
寫一個shell腳本,實現上述功能。完全殺死一個進程的命令是 kill -9 pid。
【核心要點】
kill -9 pid
#!/bin/bash #這個腳本用來完全殺死Tomcat進程 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-14 dir=/usr/local/tomcat/bin/ java_pc() { pgrep java|wc -l } cd $dir ./shutdown.sh count=0 while [ $count -lt 5 ] do n=`java_pc` if [ $n -gt 0 ] then killall java count=$[$count+1] sleep 1 else break fi done n=`java_pc` if [ $n -gt 0 ] then killall -9 java fi n=`java_pc` if [ $n -gt 0 ] then echo "Tomcat沒法強制殺死。" exit fi cd $dir ./startup.sh
實例 :
執行腳本,查看結果
注意 :
pgrep java|wc -l #把java方面的服務和進程行數,都統計出來。
while [ $count -lt 5 ] #當他關閉的次數小於5
if [ $n -gt 0 ] #當$n大於0。
8八、題目要求 : 去掉文件名後綴
至少用兩種方法,批量把當前目錄下面全部文件名後綴爲.bak的後綴去掉,好比1.txt.bak去掉後爲1.txt
【核心要點】
方法一 :用sed把文件名結尾的.bak去掉
方法二 :awk截取去掉後綴的部分,複製變量
#!/bin/bash #這個腳本用來去掉文件名後綴 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-14 for f in `ls -d ./*.bak ` do # mv $f `echo $f|sed 's/.bak$//'` f1=`echo $f|awk -F '.bak$' '{print $1}' ` mv $f $f1 done
實例 :
查看目錄下的.bak的文件
執行腳本,查看結果
腳本生成的1。1
注意 :
for f in `ls -d ./*.bak ` #表示目錄下的.bak的文件
mv $f `echo $f|sed 's/.bak$//'` #用sed把文件名結尾的.bak去掉
f1=`echo $f|awk -F '.bak$' '{print $1}' ` #awk截取去掉後綴的部分,複製變量,打印第一行。
寫一個shell腳本,查詢指定域名的過時時間,並在到期前一週,天天發一封提醒郵件。
【核心要點】
能夠在Linux下使用命令「whois域名」,如「whois aplelearn.com」 ,來獲取該域名的一些信息
#!/bin/bash #這個腳本用來檢查域名是否到期 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-14 mail_u=admin@admin.com #當前日期時間戳,用於和域名的到期時間作比較 t1=`date +%s` #檢測whois命令是否存在,不存在則安裝jwhois包 is_install_whois() { which whois >/dev/null 2>/dev/null if [ $? -ne 0 ] then yum install -y epel-release yum install -y jwhois fi } notify() { #e_d=`whois $1|grep 'Expiry Date'|awk '{print $4}'|cut -d 'T' -f 1` e_d=`whois $1|grep 'Expiration'|tail -1 |awk '{print $5}' |awk -F 'T' '{print $1}'` #若是e_d的值爲空,則過濾關鍵詞'Expiration Time' if [ -z "$e_d" ] then e_d=`whois $1|grep 'Expiration Time'|awk '{print $3}'` fi #將域名過時的日期轉化爲時間戳 e_t=`date -d "$e_d" +%s` #計算一週一共有多少秒 n=`echo "86400*7"|bc` e_t1=$[$e_t-$n] e_t2=$[$e_t+$n] if [ $t1 -ge $e_t1 ] && [ $t1 -lt $e_t ] then python mail.py $mail_u "Domain $1 will to be expired." "Domain $1 expire date is $e_d." fi if [ $t1 -ge $e_t ] && [ $t1 -lt $e_t2 ] then python mail.py $mail_u "Domain $1 has been expired" "Domain $1 expire date is $e_d." fi } #檢測上次運行的whois查詢進程是否存在 #若存在,須要殺死進程,以避免影響本次腳本執行 if pgrep whois &>/dev/null then killall -9 whois fi is_install_whois for d in aaa.com bbb.com aaa.cn do notify $d done
實例 :
在輸入欄裏面輸入」whois.chinaz.com「 ,查看某個域名的具體信息。
安裝查看域名的whois命令軟件包,
安裝YUM以後,而後就能夠安裝了
查看aminglinux.com域名的具體信息。
查詢百度的域名的過時時間。
只打印出過時的時間
執行腳本,查看結果
注意 :
which whois >/dev/null 2>/dev/null #檢測whois軟件包
e_d=`whois $1|grep 'Expiry Date'|awk '{print $4}'|cut -d 'T' -f 1` #獲取域名的過時的詳細信息,
e_d=`whois $1|grep 'Expiration'|tail -1 |awk '{print $5}' |awk -F 'T' '{print $1}'` #只打印出過時的時間
e_t1=$[$e_t-$n] #$e_t是過時時間,$n表示一週,$e_t-$n域名過時前的一週
e_t2=$[$e_t+$n] # $e_t+$n域名過時後的一週
if [ $t1 -ge $e_t ] && [ $t1 -lt $e_t2 ] #當前時間大於$e_t 域名的過時時間,而且,時間小於一週
e_d=`whois $1|grep 'Expiration Time'|awk '{print $3}'`
fi #只打印出過時的時間
if [ $t1 -ge $e_t1 ] && [ $t1 -lt $e_t ] #若是當前日期不是大於等於$e_t1的過時前的一週,而且,當前日期小於一週後的時間,表示域名過時時間不到一週了。 不到一週就過時或者過時了不到一週,就發郵件。
90、題目要求 : 自動密鑰認證
寫一個shell腳本,當咱們執行時,提示要輸入對方的ip和root密碼,而後能夠自動把本機的公鑰增長到對方機器上,從而實現密鑰認證。
【核心要點】
expect #分發腳本命令
ssh-copy-id #公鑰
#!/bin/bash #這個腳本用來自動配置密鑰認證 #做者:猿課-阿銘 www.apelearn.com #日期:2018-12-14 read -p "輸入一個IP地址: " ip read -p "輸入此機器的root密碼: " pasd is_install() { if ! rpm -q $1 &>/dev/null then yum installl -y $1 fi } is_install openssh-clients is_install expect if [ ! -f ~/.ssh/id_rsa.pub ] then echo -e "\n" |ssh-keygen -P '' fi cat > key.expect <<EOF #!/usr/bin/expect set host [lindex \$argv 0] set passwd [lindex \$argv 1] spawn ssh-copy-id root@\$host expect { "yes/no" { send "yes\r"; exp_continue} "password:" { send "\$passwd\r" } } expect eof EOF chmod a+x key.expect ./key.expect $ip $pasd
實例 :
查看機器是否安裝遠程登陸的命令軟件包和分發腳本的命令 : openssh-clients、expect
遠程登陸登陸B機器
查看本機密鑰 : cat ~/.ssh/id_rsa.pub,ssh-copy-id root@1.1.1.1把本機的公鑰增長到對方機器上,而後輸入密碼就好了。祕鑰拷貝到129機器上拷貝成功,129機器上要拷貝到祕鑰的目錄 :~/.ssh/authorized_keys
查看本機器上的祕鑰
寫一個分發腳本1.expect ,使用分發腳本登陸 B機器,而後輸入IP地址和密碼。
查看公鑰
查看祕鑰存放的目錄
查看生成的祕鑰
執行腳本,查看結果
注意 :
if ! rpm -q $1 &>/dev/null #查看命令是否運行openssh-clients、expect,若是沒有,就安裝。
if [ ! -f ~/.ssh/id_rsa.pub ] #查看本地家目錄有沒有祕鑰id_rsa.pub,若是沒有,就生成。
寫入一個分發腳本,下面是內容
set host [lindex \$argv 0]
set passwd [lindex \$argv 1]
spawn ssh-copy-id root@\$host
來源 : https://github.com/aminglinux/shell100/blob/master/61.md