shell實例100例《六》

如何讓系統的時間同步php

5一、題目要求  :  判斷網站是否正常python

寫一個shell腳本,經過curl -I 返回的狀態碼來斷定所訪問的網站是否正常。 好比,當狀態碼爲200時,纔算正常。linux

【核心要點】nginx

curl -l urlgit

如何截取狀態嗎github

參考答案

#!/bin/bash
#這個腳本用來判斷一個網址是否正常
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-11-01

url="http://www.apelearn.com/index.php"
mail_user=3067986058@qq.com

code=`curl -I $url 2>/tmp/curl.err|head -1|awk '{print $2}'`
if [ -z "$code" ]
then
    python mail.py $mail_user "$url訪問異常" "`cat /tmp/curl.err`"
    exit
elif [ $code != "200" ]
then
    curl -I $url &> /tmp/curl.log
    python mail.py $mail_user "$url訪問異常 狀態碼$code" "`/tmp/curl.log`" 
fi

實例 :ajax

經過curl -I 返回的狀態碼來斷定所訪問的網站正常shell

將錯誤的輸出重定向到/dev/null,只顯示狀態碼api

 

腳本執行的結果bash

注意  : 

elif [ $code != "200" ]                  #當code不等於200時

if [ -z "$code" ]                        #當-z爲空。

由於本腳本中沒有mail.py腳本,因此錯誤的網址,就不能記錄到/tmp/curl.err,爲了使腳本正常運行,須要放一個mail.py腳本和本腳本在同一個目錄下。

 

5二、題目要求  :  小於5k文件打包

將用戶家目錄(考慮到執行腳本的用戶多是普通用戶也多是root)下面小於5KB的文件打包成tar.gz的壓縮包,並以當前日期爲文件名前綴,例如,2018-03-15.tar.gz。

【核心要點】

find ./ -type f  -size -5k                   #查找小於5k文件

date +%F                                #打包成當前日期爲文件名前綴的壓縮包

參考答案

#!/bin/bash
#這個腳本用來打包用戶家目錄下小於5k的文件
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-11-01

t=`date +%F`
cd $HOME
tar czf $t.tar.gz `find ./ -type f -size -5k|xargs`

實例 :

查找小於5k的文件

查找小於5k的文件,使用xargs命令,全部的文件只顯示在一行。

當前用戶的家目錄

執行腳本,查看結果

查看壓縮打包的內容

注意  : 


t=`date +%F`                               #打印出當前系統時間

 

 

5三、題目要求    監控22端口是否被封

一個同窗不當心用iptables規則把sshd端口22給封掉了,結果不能遠程登錄,要想解決這問題,還要去機房,登陸真機去刪除這規則。 問題來了,要寫個監控腳本,監控iptables規則是否封掉了22端口,若是封掉了,給打開。 寫好腳本,放到任務計劃裏,每分鐘執行一次。

【核心要點】

一、如何判斷是否封掉22端口是本題關鍵點

二、思路是查看iptables INPUT鏈規則,看是否有目標端口爲22,的規則,而且規則target爲DROP或者REJECT。有這兩個,說明被封了。

參考答案

#!/bin/bash
#這個腳本用來解封22端口
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-11-01

iptables -nvL INPUT --line-numbers |grep -w 'dpt:22' |awk '$4 ~/REJECT|DROP/ {print $1}' > /tmp/iptables.log
n=`wc -l /tmp/iptables.log`

if [ $n -gt 0 ]
then
    for n in `tac /tmp/iptables.log`
    do
	iptables -D INPUT $n
    done
fi

實例 :

查看全部的iptbale鏈,刪除規則2,命令 : 「iptables -D INPUT 2」

給IPTABLES的22端口寫兩個規則,DROP,REJECT

iptables規則中過濾出,含有dpt:22的行

iptables規則中過濾出,含有dpt:22的行,找出第三行,含有REJECT或者DROP的行

使用line-number查找含有含有REJECT或者DROP的行

添加規則

只顯示含有REJECT或者DROP的行,只打印出來行號

先刪除第一個規則,而後查看只顯示含有REJECT或者DROP的行,只打印出來行號。【注意: 刪除的規則,應該從最底下的規則5,開始刪除】

執行腳本,查看腳本運行的結果

 

注意  : 

iptables -nvL INPUT --line-numbers |grep -w 'dpt:22' |awk '$4 ~/REJECT|DROP/ {print $1}' > /tmp/iptables.log                  #iptables規則中過濾出,含有dpt:22的行,找出第四行,含有REJECT或者DROP的行

$n -gt 0                          #$n大於了,開始解封

for n in `tac /tmp/iptables.log`                #倒敘解封,/tmp/iptables.log

 

5四、題目要求   : 分析日誌

已知nginx訪問的日誌文件在/usr/local/nginx/logs/access.log內,請統計下早上10點到12點 來訪ip最多的是哪一個?

參考日誌

111.199.186.68 – [15/Sep/2017:09:58:37 +0800]  「//plugin.php?id=security:job」 200 「POST //plugin.php?id=security:job HTTP/1.1″」http://a.lishiming.net/forum.php?mod=viewthread&tid=11338&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline」 「Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3141.7 Safari/537.36」
203.208.60.208 – [15/Sep/2017:09:58:46 +0800] 「/misc.php?mod=patch&action=ipnotice&_r=0.05560809863330207&inajax=1&ajaxtarget=ip_notice」 200 「GET /misc.php?mod=patch&action=ipnotice&_r=0.05560809863330207&inajax=1&ajaxtarget=ip_notice HTTP/1.1″」http://a.lishiming.net/forum.php?mod=forumdisplay&fid=65&filter=author&orderby=dateline」 「Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3141.7 Safari/537.36」

【核心要點】

一、須要截取10點到12點之間的日誌,思路是用grep過濾時間關鍵字。

二、請求的IP在日誌中在第一段,用awk截取便可。

參考答案

#!/bin/bash
#這個腳本用來分析Nginx訪問日誌
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-11-01

export LANG=en
log="/usr/local/nginx/logs/access.log"
t=`date +%d/%b/%Y:1[01]:[0-5][0-9]:`

egrep "$t" $log|awk '{print $1}' |sort -n |uniq -c |sort -n |tail -1 |awk '{print $2}'

實例 :

執行腳本,查看腳本運行的結果

注意  : 

t=`date +%d/%b/%Y:1[01]:[0-5][0-9]:`                     #截取10,11點兩個小時的日誌,是時間59分59秒

egrep "$t" $log|awk '{print $1}' |sort -n |uniq -c |sort -n |tail -1 |awk '{print $2}'                                 #排序,統計行數,排序,截取第二行

 

 

5五、題目要求    打印數字

寫一個shell腳本。提示輸入一個暫停的數字,而後從1打印到該數字。而後詢問是否繼續。繼續的話再輸入一個數字接着打印,不然退出腳本。

例:若是輸入的是5,打印1 2 3 4 5,而後繼續輸入15,而後打印6 7 …14 15 以此類推。

【核心要點】

一、根據題目要求,首先用read -p 提示用戶輸入數字,獲取到第一個數字。

二、此時須要判斷用戶輸入的是純數字。

三、第一次循環後,若用戶繼續輸入數字,此時不只要判斷輸入的是是不是純數字,還要判斷輸入的數字是否比第一個數字大。

參考答案

#!/bin/bash
#這個腳本用來打印數字
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-11-01

read -p "Please input a number: " n
n1=`echo $n |sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
    echo "Please input a number."
    exit
fi

for i in `seq 1 $n`
do
    echo $i
done

read -p "If continue? y/n" c

case $c in
  n|N)
    exit
    ;;
  y|Y)
    read -p "Please input a number: " n2
    n3=`echo $n2|sed 's/[0-9]//g'`
    if [ -n "$n3" ]
    then
	echo "Please input a number."
	exit
    fi
    if [ $n2 -le $n ]
    then
	echo "$n2 should grater than $n."
        exit
    fi
    for i in `seq $[$n+1] $n2`
    do
	echo $i
    done
    ;;
  *)
    echo "Please input y or n."
    ;;
esac

實例 :

執行腳本,查看腳本運行的結果

注意  : 

if [ -n "$n1" ]                          #第一次執行,若是$n1 不爲空,提示"Please input a number.",而後退出腳本

n1=`echo $n |sed 's/[0-9]//g'`                   #清空全部的數字

 

 n3=`echo $n2|sed 's/[0-9]//g'`                   #清空全部的數字

 for i in `seq $[$n+1] $n2`                        #

for i in `seq 1 $n`                        #打印全部的數字,而後提示 「"If continue? y/n"」

if [ $n2 -le $n ]                                                    #$n2小於等於1,提示 "$n2 should grater than $n."

 

5六、題目要求 :  打印數字

在文本文檔1.txt第5行(假設文件行數大於5)後面增長以下內容:

# This is a test file.
# Test insert line into this file.

【核心要點】

一、給文檔指定行後面增長內容,可使用sed搞定

二、比較笨的方法是,依次按順序打印前5行,而後打印要增長的行,再從文本第6行開始一直到結束依次打印剩餘的行。

參考答案

#!/bin/bash
#這個腳本用來給文件增長行
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-11-01

n=0
cat 1.txt |while read line
do
    n=$[$n+1]
    if [ $n -eq 5 ]
    then
        echo $line
	echo -e "# This is a test file.\n# Test insert line into this file."
    else
	echo $line
    fi
done

實例 :

寫一個文檔1.txt,添加內容

在文檔中,第五、6行添加內容

在文檔中,第5行增長兩行內容,使用\n

在文檔中,第5行增長兩行內容,

執行腳本,查看腳本運行的結果

注意  : 

n=0                       #n是計數器

line                          #line  是變量

  if [ $n -eq 5 ]                      #等於第五行

echo $line                                   #第一個echo $line,是打印第5行的意思

 


5七、題目要求 :  備份etc目錄

設計一個shell程序,在每個月第一天備份並壓縮/etc目錄的全部內容,存放在/root/bak目錄裏,且文件名爲以下形式"yymmdd_etc.tar.gz",yy爲年,mm爲月,dd爲日。

【核心要點】

一、yymmdd用date +%y%m%d表示

二、每個月第一天,須要判斷date +%d是不是01

參考答案

#!/bin/bash
#這個腳本用來備份/etc/目錄
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-02

d1=`date +%d`
d2=`date +%y%m%d`

if [ $d1 == "01" ]
then
    cd /etc/
    tar czf /root/bak/$d2_etc.tar.gz ./
fi

實例 :

date +%d是不是01,大寫的Y,表示顯示4位數。

執行腳本,查看腳本運行的結果

注意  : 


if [ $d1 == "01" ]                                    #若是是01,執行下面的指令

   tar czf /root/bak/$d2_etc.tar.gz ./                 #打包到 /root/bak/$d2_etc.tar.gz,

 

5八、題目要求  :  找出重複的單詞

將文件內全部的單詞的重複次數計算出來,只須要列出重複次數最多的10個單詞。

【核心要點】

把非英文的字符刪除掉(用空格替換),剩下的就是英文字母或者單詞。 

參考答案

#!/bin/bash
#這個腳本用來找出重複的單詞
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-02

for w in `sed 's/[^a-zA-Z]/ /g' $1`
do
    echo $w
done |sort |uniq -c |sort -nr|head

實例 :

/etc/passwd文件在中將全部非英文字母,替換成空格、全局

/etc/passwd文件在中將全部非英文字母,替換成空格、全局,顯示在一列。

查看前10列

執行腳本,查看腳本運行的結果

注意  : 

 done |sort |uniq -c |sort -nr|head                            #排序,統計行數,排序,查看前10列

 

5九、題目要求   :  人員分組

需求是,把全部的成員平均分紅若干個小組。這裏,提供一我的員列表,好比成員有50人,須要分紅7個小組,要求隨機性,每次和每次分組的結果應該不一致。

【核心要點】

一、首先肯定好要分的小組個數,本題中假設有50人,分7個小組,平均每一個小組個數應爲7。

二、爲了實現隨機性,咱們能夠根據人名的長度來作一個運算,好比用一個隨機數+人名的長度獲得一個隨機數,而後除以7取餘數,餘數是幾就把該用戶分到第幾組裏。

三、考慮到人員數量較少,最終分組結果必定不均衡,好比,有的小組分了10我的,但有的小組卻分到了3我的,這樣嚴重不均衡。

四、爲了讓人員更加均衡,須要把人數偏多的組(大於7的)均分一部分紅員到人數偏少的組(小於7的)。

參考人員名單

xiaoguisheng
guoyuqing
xiongyongzheng
mengjintang
chaizuzhou
zhousheng
xufangming
zhaoliangyun
hanshiru
wangxianyi
zhangjipei
luxiuli
yangshugen
guoyongzhi
lijianguo
wuqiongchen
dinglin
yaoyashan
yinzijia
wangbencheng
liuxiuwen
chenzuqi
leyuguo
baozongyao
fenghao
sunxiaoquan
zhangyaxian
lijiuzhe
dulichun
lixi
shenpeiwen
zousilin
luoping
chaiyan
fandaozhang
huzixiang
jinzhen
zhujunfeng
liqianbiao
hangyanliang
luorenjian
loujianji
fujianzhou
gengyiwu
jinjigui
liuzhizhong
lisanyan
lisili
zhangyiyu
songguozhen
zhangxinghua
zhaozhiyong
huanghe
xiaojie
fanhongfei
wangguiwen
renshumin
songfuying
zhanghaibo
liguangqun
puaihua
yanzhihua
gaojixian
liulai
funing
chenruizhi
chendaxin
laishaoying
xujian
xiaozhekou
xuxiaping
jiangchunqing

參考答案

【核心要點】

#!/bin/bash
#這個腳本用來給人員分組
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-02

#人員列表文件
f=member.txt
#小組數
group_n=7
#人員總數
member_n=`wc -l $f|awk '{print $1}'`

#根據姓名計算該用戶所在小組的id
get_n()
{
    #根據姓名計算cksum值
    l=`echo $1|cksum|awk '{print $1}'`
    #獲取一個隨機數
    n1=$RANDOM
    #cksum值和隨機數相加,而後除以小組數取餘,這樣能夠確保每次獲取到的餘數都不同
    n2=$[$n1+$l]
    g_id=$[$n2%$group_n]
    #假如小組數爲7,則餘數範圍0-6,若是餘數爲0,則小組爲7
    if [ $g_id -eq 0 ]
    then
        g_id=$group_n
    fi
    echo $g_id
}

for i in `seq 1 $group_n`
do
    #n_$i.txt爲臨時文件,用來記錄該小組內的成員
    #腳本以前執行過,則該文件會存在,本次執行腳本前應該刪除掉這個臨時文件
    [ -f n_$i.txt ] && rm -f n_$i.txt
done


shuf $f|while read name
do
    #計算用戶所在小組的id
    g=`get_n $name`
    #將人員追加寫入到他對應的小組裏
    echo $name >> n_$g.txt
done

#定義計算文件行數的函數
nu(){
    wc -l $1|awk '{print $1}'
}

#獲取組員人數最多的小組
max(){
    ma=0
    for i in `seq 1 $group_n|shuf`
    do
        n=`nu n_$i.txt`
        if [ $n -gt $ma ]
        then
            ma=$n
       fi
    done
    echo $ma
}

#獲取組員人數最少的小組
min(){
    mi=$member_n
    for i in `seq 1 $group_n|shuf`
    do
       n=`nu n_$i.txt`
       if [ $n -lt $mi ]
       then
           mi=$n
       fi
    done
    echo $mi
}

#定義四捨五入函數
div()
{
    n=`echo "scale=1;$1/$2"|bc`
    n1=`echo "scale=1;$n+0.5"|bc`
    echo $n1|cut -d. -f1
}

#小組組員平均值(非四捨五入)
ava_n=$[$member_n/$group_n]
#小組組員平均值(四捨五入)
ava_n1=`div $member_n $group_n`

if [ $ava_n -eq $ava_n1 ]
then
    #定義初始最小值
    ini_min=1
    #如下while循環要作的事情,就是要把人數多的組裏的人搞到人數少的組裏去
    #此while循環的條件是,當人數最少的組成員數小於組員平均值
    while [ $ini_min -lt $ava_n1 ]
    do
        #找出人數最多的組
        m1=`max`
        #找出人數最少的組
        m2=`min`
        for i in `seq 1 $group_n|shuf`
        do
            n=`nu n_$i.txt`
            #找到人數最多的組對應的文件f1(可能有多個,這裏取出現的第一個便可)
            if [ $n -eq $m1 ]
            then
                f1=n_$i.txt
            #找到人數最少的組對應的文件f2(可能有多個,這裏取出現的第一個便可)
            elif [ $n -eq $m2 ]
            then
                f2=n_$i.txt
            fi
        done
        #取f1中最後一我的名
        name=`tail -n1 $f1`
        #將這我的名追加寫入f2中
        echo $name >> $f2
        #在f1中刪除剛剛取走的人名
        sed -i "/$name/d" $f1
        #把此時的最少組人員數賦值給ini_min
        ini_min=`min`
    done
else
    #定義初始最大值
    ini_max=$member_n
    while [ $ini_max -gt $ava_n1 ]
    do
        #找出人數最多的組
        m1=`max`
        #找出人數最少的組
        m2=`min`
        for i in `seq 1 $group_n|shuf`
        do
            n=`nu n_$i.txt`
            #找到人數最多的組對應的文件f1(可能有多個,這裏取出現的第一個便可)
            if [ $n -eq $m1 ]
            then
                f1=n_$i.txt
                #找到人數最少的組對應的文件f2(可能有多個,這裏取出現的第一個便可)
            elif [ $n -eq $m2 ]
            then
                f2=n_$i.txt
            fi
        done
        #取f1中最後一我的名
        name=`tail -n1 $f1`
        #將這我的名追加寫入f2中
        echo $name >> $f2
        #在f1中刪除剛剛取走的人名
        sed -i "/$name/d" $f1
        #把此時的最少組人員數賦值給ini_min
        ini_max=`max`
    done
fi

for i in `seq 1 $group_n`
do
    echo -e "\033[34m$i 組成員有:\033[0m"
    cat n_$i.txt
    #把臨時文件刪除
    rm -f n_$i.txt
    echo
done

實例 :

執行腳本,查看腳本運行的結果

注意  : 

要bc命令,bc是一個計算器,須要使用:yum install -y bc

member_n=`wc -l $f|awk '{print $1}'`                               #統計人員總數和行數

shuf $f|while read name                                    #將小組人員,隨機分配。

echo -e "\033[34m$i 組成員有:\033[0m"                                #

 

 

60、題目要求   :   比較兩個數大小

寫一個shell腳本,比較兩個數的大小,支持浮點數,兩個數經過shell參數的形式提供。

【核心要點】

參考答案

#!/bin/bash
#這個腳本用來比較兩個數大小
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-05

if [ $# -ne 2 ]
then
    echo "請提供兩個參數."
    exit
fi

if_number() 
{
    if echo $1|grep -q '^-'
    then
	nu=`echo $1|sed 's/^-//'`
    else
	nu=$1
    fi
    n=`echo $nu|sed 's/[0-9.]//g'`
    if [ -n "$n" ]
    then
	echo "$1不是合法數字."
	exit
    fi
    if echo $1|grep -q '^\.'
    then
	echo "$1不是合法數字."
	exit
    fi
}

if_number $1
if_number $2

n1=`echo "$1>$2"|bc`
if [ $n1 -eq 1 ]
then
    echo "$1 > $2"
else
    if [ "$1" == "$2" ]
    then
	echo "$1 = $2"
    else
	echo "$1 < $2"
    fi
fi

實例 :

執行腳本,查看腳本運行的結果

注意  : 

 

寫一個腳本,add_title.sh,寫入前綴,而後執行:sh add_title.sh 12.sh,將前綴寫入12腳本中

執行結果

 

 

來源 :https://github.com/aminglinux/shell100/blob/master/13.md

相關文章
相關標籤/搜索