shell實例100例《九》

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

要求:

  1. 這個腳本能夠取tomcat實例t1-t4的日誌
  2. 這個腳本能夠自定義取日誌的起始點 ,好比取今天早上10點以後到如今的數據
  3. 這個腳本能夠自定義取日誌的起始點和終點,好比取今天早上9點到晚上8點的數據 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

 

8五、題目要求  :    統計併發量

需求背景:

須要統計網站的併發量,並繪圖。 說明: 只須要寫出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截取去掉後綴的部分,複製變量,打印第一行。

 

8九、題目要求   :     檢查域名是否到期

寫一個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

相關文章
相關標籤/搜索