shell實例100例《二》

十一、題目要求node

寫一個腳本實現以下功能:  輸入一個數字,而後運行對應的一個命令。python

顯示命令以下:linux

*cmd meau**  1 - date 2 - ls 3 - who 4 - pwd 當輸入1時,會運行date, 輸入2時運行ls, 以此類推。git

核心要點

  • case判斷

參考答案

#!/bin/bash
echo "*cmd meau**  1 - date 2 - ls 3 - who 4 - pwd"
read -p "Please input a number: " n
if [ -z "$n" ]
then
    echo "請輸入一個純數字,範圍1-4."
    exit
fi

n1=`echo $n|sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
    echo "請輸入一個純數字,範圍1-4."
    exit
fi

case $n in 
    1)
	date
	;;
    2)
	ls
	;;
    3)
	who
	;;
    4)
	pwd
	;;
    *)
	echo "請輸入1-4的數字"
        ;;
esac

注意 :github

使用  -n "$n"判斷一個變量是否爲空web

當一個數字    -z "$n"   爲1時,輸出1的指定命令     shell

 

十二、題目要求apache

用shell腳本實現以下需求:bash

添加user_00 – user_09 10個用戶,而且給他們設置一個隨機密碼,密碼要求10位包含大小寫字母以及數字,注意須要把每一個用戶的密碼記錄到一個日誌文件裏。   提示:服務器

  1. 隨機密碼使用命令 mkpasswd

  2. 在腳本中給用戶設置密碼,可使用echo 而後管道passwd命令

核心要點

  • seq實現數字遞增
  • mkpasswd產生隨機字符

參考答案

#!/bin/bash
for i in `seq -w 00 09`
do
    useradd user_$i
    p=`mkpasswd -l 10 -s 0 `
    echo "user_$i $p" >> /tmp/pass.tmp
    echo $p |passwd --stdin user_$i
done

注意 : 

seq -w 00 09       #查找00到09之間的數字

mkpasswd -l 10 -s 0          #生成隨機密碼要求10位包含大小寫字母以及數字

 

# echo "asdhdkjhakushd kjhskjd" | passwd --stdin user1                 #  更新用戶user的密碼

 

使用命令     tail /etc/passwd       查看用戶的隨機密碼,有沒有生成。

使用命令   cat /tmp/pass.tmp          查看用戶的隨機密碼,有沒有生成。

 

在另外一臺機器上,測試用戶的隨機密碼能不能登陸

#ssh user_00@aming

password :輸入密碼

 

而後刪除建立的用戶的隨機密碼

# for i in 'seq -w 00 09 '; do userdel -r user_$i; done

使用命令     tail /etc/passwd     查看密碼有沒有刪除成功

 

1三、題目要求

在服務器上,寫一個監控腳本,要求以下:

  1. 每隔10s去檢測一次服務器上的httpd進程數,若是大於等於500的時候,就須要自動重啓一下apache服務,並檢測啓動是否成功?

  2. 若沒有正常啓動還需再一次啓動,最大不成功數超過5次則須要當即發郵件通知管理員,而且之後不須要再檢測!

  3. 若是啓動成功後,1分鐘後再次檢測httpd進程數,若正常則重複以前操做(每隔10s檢測一次),若仍是大於等於500,那放棄重啓並須要發郵件給管理員,而後自動退出該腳本。假設其中發郵件腳本爲以前使用的mail.py

核心要點

  • pgrep -l httpd或者ps -C httpd --no-heading檢查進程
  • for循環5次計數器

參考答案

#!/bin/bash
check_service()
{
    n=0
    for i in `seq 1 5`
    do
        /usr/local/apache2/bin/apachectl restart 2>/tmp/apache.err
        if [ $? -ne 0 ]
        then
            n=$[$n+1]
        else
            break
        fi
    done
    if [ $n -eq 5 ]
    then
        ##下面的mail.py參考https://coding.net/u/aminglinux/p/aminglinux-book/git/blob/master/D22Z/mail.py
        python mai.py "123@qq.com" "httpd service down" `cat /tmp/apache.err`
        exit
    fi
}   
while true
do
    t_n=`ps -C httpd --no-heading |wc -l`
    if [ $t_n -ge 500 ]
    then
        /usr/local/apache2/bin/apachectl restart
        if [ $? -ne 0 ]
        then
            check_service
        fi
        sleep 60
        t_n=`ps -C httpd --no-heading |wc -l`
        if [ $t_n -ge 500 ]
        then
            python mai.py "123@qq.com" "httpd service somth wrong" "the httpd process is busy."
            exit
        fi
    fi
    sleep 10
done

注意  : 

!$? -ne 0             #  表示輸出的結果不等於0,

$n -eq 5             # 表示輸出的結果等於5,表示重啓不成功,發郵件給管理員。

 

/usr/local/apache2/bin/apachectl restart 2>/tmp/apache.err        #若是進程數爲0 ,就重啓,不然就輸出到/tmp/apache.err  日誌文件中

ps -C httpd --no-heading |wc -l`             #統計進程數量

$t_n -ge 500                         #若是apache重啓一分鐘後進程數,仍大於500,啓動check_service,就登陸服務器查看問題

 

 

1四、題目要求

需求: 根據web服務器上的訪問日誌,把一些請求量很是高的ip給拒絕掉!而且每隔半小時把再也不發起請求或者請求量很小的ip給解封。   假設: 

  1. 一分鐘內請求量高於100次的IP視爲不正常請求。

  2. 訪問日誌路徑爲/data/logs/access_log。

用第2例中的1.log做爲演示日誌

核心要點

  • 統計ip訪問次數,排序
  • 如何標記每隔半小時
  • iptables計數器是一個重要的判斷指標
  • 函數(封IP、解封IP)

參考答案

#!/bin/bash
block_ip()
{
t1=`date -d "-1 min" +%Y:%H:%M`
log=/data/logs/access_log

egrep "$t1:[0-9]+" $log > /tmp/tmp_last_min.log
awk '{print $1}' /tmp/tmp_last_min.log |sort -n |uniq -c|sort -n |awk '$1>100 {print $2}' > /tmp/bad_ip.list 
n=`wc -l /tmp/bad_ip.list|awk '{print $1}'`
if [ $n -ne 0 ]
then
    for ip in `cat /tmp/bad_ip.list`
    do
	iptables -I INPUT -s $ip -j REJECT
    done
fi
}

unblock_ip()
{
    iptables -nvL INPUT|sed '1d' |awk '$1<5 {print $8}' > /tmp/good_ip.list
    n=`wc -l /tmp/good_ip.list|awk '{print $1}'`
    if [ $n -ne 0 ]
    then
    for ip in `cat /tmp/good_ip.list`
    do
	iptables -D INPUT -s $ip -j REJECT
    done
    fi
    iptables -Z
}

t=`date +%M`
if [ $t == "00" ] || [ $t == "30" ]
then
   unblock_ip
   block_ip
else
   block_ip
fi

注意  : 

使用命令  :head 1.log  查看日誌的內容

grep 2018:02:12:[0-9]+ 1.log            #查看2018年的日誌

實例  : 

# t1='date -d "-1 min" +%Y:%H:%M'                #指定一個變量

# echo $t1                    #上一分鐘,用變量的形式表示出來,

2019:12:12

#  egrep "$t1:[0-9]+" 1.log              # 截取出來1.log日誌中上一分鐘,全部的日誌,     

注意  :egrep   使用變量,使用雙引號

 

sort -n |uniq -c|sort -n               #表示排序,去重複,在排序

awk '$1>100 {print $2}' > /tmp/bad_ip.list                    #大於100的,寫入/tmp/bad_ip.list中去

iptables -I INPUT -s $ip -j REJECT                  #把一些請求量很是高的ip給拒絕掉!

 

iptables -nvL INPUT|sed '1d' |awk '$1<5 {print $8}'  > /tmp/good_ip.list           #符合條件的IP,寫入到/tmp/good_ip.list 文件中

#sed '1d'                #過濾掉iptables -nvL INPU顯示出來的 第一行    

#print $8              #表示iptables -nvL INPU顯示出來的,第八列,$8表示顯示出來的IP地址

 

# iptbales -nvL INPUT                                                    #查看封掉的IP

# iptbales -Z INPUT                                              #INPUT鏈裏面的全部規則清空,從新計數。

查看時間,22分鐘以前的時間點

 

[ $t == "00" ] || [ $t == "30" ]                    #表示當時間爲00分鐘或者30分鐘時,執行一次解封腳本。

 

1五、題目要求

請仔細查看以下幾個數字的規律,並使用shell腳本輸出後面的十個數字。

10 31 53 77  105 141 …….

核心要點

  • 計算兩個數值之間的差值

參考答案

#!/bin/bash
x=10
y=21
for i in `seq 0 15`
do 
    echo $x
    x=$[$x+$y]
    z=$[2**$i]
    y=$[$y+$z]
done

案例 :

# for i  in 'seq 0 3'; do z=$[2**$i]; echo $z; done

1

2

4

8

# y=21; for i in 'seq 0 3'; do echo $y; z=$[2**$i]; y=$[$y+$z]; done

21

22

24

28

# x=10; y=21; for i in 'seq 0 3'; do echo $y; z=$[2**$i]; y=$[$y+$z]; done

10

31

53

z=$[2**$i]                    #表示2的$i次方

 

1六、題目要求

寫個shell,看看你的Linux系統中是否有自定義用戶(普通用戶),如果有,一共有幾個?

參考答案

#!/bin/bash
v=`awk -F 'release ' '{print $2}' /etc/redhat-release |cut -d '.' -f1`
user()
{
      if [ $1 -eq 0 ]
      then
          echo "系統沒有自定義的用戶"
      else
          echo "系統存在自定義用戶,有$1個"
      fi
}
case $v in 
  5|6)
      n=`awk -F ':' '$3>=500' /etc/passwd|wc -l`
      user $n
  ;;
  7)
      n=`awk -F ':' '$3>=1000' /etc/passwd|wc -l`
      user $n
  ;;
  *)
     echo "腳本出錯."
  ;;
esac

案例 : 

# cat /etc/redhat-release                                #查看系統版本

CentOS Linux release 7.4.1708 (Core)

# awk -F 'release' '{print $2}' /etc/redhat-release 

7.4.1708 (Core)

# awk -F ':' '$3 >=500' /etc/passwd                  #查看大於500的自定義用戶的個數

注意  :5,6,7表明的是獲得的用戶的個數結果是5,6,7,若是不是,表示腳本出錯

   

1七、題目要求

寫一個shell腳本,檢測全部磁盤分區使用率和inode使用率並記錄到以當天日期爲命名的日誌文件裏,當發現某個分區容量或者inode使用量大於85%時,發郵件通知你本身。

參考答案

#!/bin/bash
dir=/tmp/disk
d=`date +%F`
mail=123@123.com

[ -d $dir ] || mkdir $dir

df >> $dir/$d.log
df -i >> $dir/$d.log

df|sed '1d' |awk -F ' +|%' '$5>=85 {print $7}' > $dir/df.tmp
df -i|sed '1d' |awk -F ' +|%' '$5>=85 {print $7}' > $dir/df_i.tmp

n1=`wc -l $dir/df.tmp|awk '{print $1}'`
n2=`wc -l $dir/df_i.tmp|awk '{print $1}'`

tag=0
if [ $n1 -gt 0 ]
then
    if [ $n2 -gt 0 ]
    then
	tag=11
    else
	tag=10
    fi
else
    if [ $n2 -gt 0 ]
    then
	tag=01
    else
	tag=00
    fi
fi

case $tag in
    11)
	python mail.py $mail "磁盤空間和inode使用率高於85%" "`cat $dir/df.tmp $dir/df_i.tmp|xargs`"
        ;;
    10)
	python mail.py $mail "磁盤空間使用率高於85%" "`cat $dir/df.tmp|xargs`"
	;;
    01)
	python mail.py $mail "磁盤inode使用率高於85%" "`cat $dir/df_i.tmp|xargs`"
	;;
    *)
	;;
esac

實例 : 

# df                         #查看的是空間使用量

# df -i                     #查看的是inode使用率

# df | awk '{print $5}'                   #查看df顯示出來的,第五段信息磁盤使用率

# df | awk '{print $5}' |sed 's/%//'                  #查看df顯示出來的,第五段信息磁盤使用率,去掉百分號;df | awk '{print $5}' |sed 's/[%.]//'    同一個意思

# df |sed '1d' | awk -F ' +|%' '$5<=85 {print $6}'                         #顯示並打印出第六列,使用率大於85%的磁盤

 

$n1 -gt 0                         #當$n1等於0時,使用率大於等於85%,發郵件。

n2 -gt 0                #當$n2等於0時,innode大於等於85%,發郵件。

 

1八、題目要求

有一臺服務器做爲web應用,有一個目錄(/data/web/attachment)不定時地會被用戶上傳新的文件,可是不知道何時會上傳。因此,須要咱們每5分鐘作一次檢測是否有新文件生成。

請寫一個shell腳本去完成檢測。檢測完成後如果有新文件,還須要將新文件的列表輸出到一個按年、月、日、時、分爲名字的日誌裏。

參考答案

#!/bin/bash
basedir=/data/web/attachment
t=`date +%Y%m%d%H%M`

find $basedir/ -type f -mmin -5 > /tmp/file.list
n=`wc -l /tmp/file.list|awk '{print $1}'`
if [ $n -lt 0 ]
then
   mv /tmp/file.list /tmp/$t.list
fi

案例 :

find $basedir/ -type f -mmin -5 > /tmp/file.list                #小於5分鐘生成的新文件寫入到 /tmp/file.list 文件中去  。

$n -lt 0                                #若是大於零的,把文件移到/tmp/file.list /tmp/$t.list文件中去

 

1九、題目要求

寫一個shell腳原本看看你使用最多的命令是哪些,列出你最經常使用的命令top10。

參考答案

cat ~/.bash_history |sort |uniq -c |sort -nr |head

 

 

20、題目要求

假如須要每小時都去執行一個腳本。在腳本中實現這樣的功能,當時間是0點和12點時,須要將目錄/data/log/下的文件所有清空,

注意只能清空文件內容而不能刪除文件。而其餘時間只須要統計一下每一個文件的大小,一個文件一行,輸出到一個按日期和時間爲名字的日誌裏。

須要考慮/data/log/目錄下的二級、三級、…  等子目錄裏面的文件。

參考答案

#!/bin/bash
dir=/tmp/log_stat
t=`date +%d%H`
t1=`date +%H`
logdir=/data/log

[ -d $dir ] || mkdir $dir
[ -f $dir/$t.log ] && rm -f $dir/$t.log

if [ $t == "00" -o $t1 == "12" ]
then
    for f in `find $logdir/ -type f`
    do
	> $f
    done
else
    for f in `find $logdir/ -type f`
    do
	du -sh $f >> $dir/$t.log
    done
fi

案例  :

先建立   目錄   

# mkdir -p /data/log/

再執行腳本

 

 

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

相關文章
相關標籤/搜索