101個(gè)shell腳本

【腳本1】打印形狀

打印等腰三角形蒜埋、直角三角形、倒直角三角形吆录、菱形

#!/bin/bash
# 等腰三角形
read -p "Please input the length: " n
for i in `seq 1 $n`
do
   for ((j=$n;j>i;j--))
   do
      echo -n " "
   done

   for m in `seq 1 $i`
   do
     echo -n "* "
   done
   echo 
done

# 倒直角三角形
read -p "Please input the length: " len
for i in `seq 1 $len`
do
    for j in `seq $i $len`
    do
       echo -n "* "
    done
    echo
done

# 直角三角形
read -p "Please input the length: " len
for i in `seq 1 $len`
do
    for((j=1;j<=$i;j++))
    do
       echo -n "* "
    done
    echo
done

# 菱形
read -p "Please input the length: " n

for i in `seq 1 $n`
do
   for ((j=$n;j>i;j--))
   do
      echo -n " "
   done
   for m in `seq 1 $i`
   do
     echo -n "* "
   done
   echo 
done

for i in `seq 1 $n`
do
    for((j=1;j<=$i;j++))
    do
       echo -n " "
    done
    for((k=$i;k<=$len-1;k++))
    do
          echo -n "* "
    done
    echo 
done

【腳本2】截取字符串

現(xiàn)有一個(gè)字符串如下:

http://www.aaa.com/root/123.htm

請(qǐng)根據(jù)以下要求截取出字符串中的字符:

1.取出www.aaa.com/root/123.htm

2.取出123.htm

3.取出http://www.aaa.com/root

4.取出http:

5.取出http://

6.取出www.aaa.com/root/123.htm

7.取出123

8.取出123.htm

#!/bin/bash
var="http://www.aaa.com/root/123.htm"
#1.
echo $var |awk -F '//' '{print $2}'
#2.
echo $var |awk -F '/' '{print $5}'
#3.
echo $var |grep -o 'http.*root'
#4.
echo $var |awk -F '/' '{print $1}'
#5.
echo $var |grep -o 'http://'
#6.
echo $var |grep -o 'www.*htm'
#7.
echo $var |grep -o '123'
#8.
echo $var |grep -o '123.htm'

【腳本3】tomcat啟動(dòng)腳本

emm赠尾。良漱。這個(gè)腳本是因?yàn)閠omcat沒有自帶的能夠給service開機(jī)啟動(dòng)的腳本,我就琢磨著自己寫了一個(gè)簡(jiǎn)單的啟動(dòng)腳本睦番,如下:

#!/bin/bash
# chkconfig:2345 64 36
# description: Tomcat start/stop/restart script.

### BEGIN INIT INFO
# Provides: tomcat
# Required-Start: 
# Should-Start: 
# Required-Stop: 
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop Tomcat
# Description: Tomcat Service start&restart&stop script
### END INIT INFO

##Written by zero.##
JAVA_HOME=/usr/local/jdk1.8/
JAVA_BIN=/usr/local/jdk1.8/bin
JRE_HOME=/usr/local/jdk1.8/jre
PATH=$PATH:/usr/local/jdk1.8/bin:/usr/local/jdk1.8/jre/bin
CLASSPATH=/usr/local/jdk1.8/jre/lib:/usr/local/jdk1.8/lib:/usr/local/jdk1.8/jre/lib/charsets.jar
TOMCAT_BIN=/usr/local/tomcat/bin
RETVAL=0
prog="Tomcat"

start()
{
   echo "Starting $prog......"
   /bin/bash $TOMCAT_BIN/startup.sh
   RETVAL=$?
   return $RETVAL
}
stop()
{
   echo "Stopping $prog......"
   /bin/bash $TOMCAT_BIN/shutdown.sh
   RETVAL=$?
   return $RETVAL
}
restart(){
   echo "Restarting $prog......"
   stop
   start
}

case "$1" in
   start)
        start
        ;;
   stop)
       stop
       ;;
   restart)
       restart
       ;;
   *)
       echo $"Usage: $0 {start|stop|restart}"
       RETVAL=1
esac
exit $RETVAL

【腳本4】自定義rm命令

linux系統(tǒng)的rm命令太危險(xiǎn)类茂,一不小心就會(huì)刪除掉系統(tǒng)文件。 寫一個(gè)shell腳本來替換系統(tǒng)的rm命令托嚣,要求當(dāng)刪除一個(gè)文件或者目錄時(shí)巩检,都要做一個(gè)備份,然后再刪除示启。下面分兩種情況兢哭,做練習(xí):

1. 簡(jiǎn)單的實(shí)現(xiàn):

假設(shè)有一個(gè)大的分區(qū)/data/,每次刪除文件或者目錄之前夫嗓,都要先在/data/下面創(chuàng)建一個(gè)隱藏目錄迟螺,以日期/時(shí)間命名冲秽,比如/data/.201703271012/,然后把所有刪除的文件同步到該目錄下面矩父,可以使用rsync -R 把文件路徑一同同步劳跃,示例:

#!/bin/bash
fileName=$1
now=`date +%Y%m%d%H%M`
read -p "Are you sure delete the file or directory $1? yes|no: " input

if [ $input == "yes" ] || [ $input == "y" ]
then
    mkdir /data/.$now
    rsync -aR $1/ /data/.$now/$1/
    /bin/rm -rf $1
elif [ $input == "no" ] || [ $input == "n" ]
then
    exit 0
else
    echo "Only input yes or no"
    exit
fi

2.復(fù)雜的實(shí)現(xiàn):

不知道哪個(gè)分區(qū)有剩余空間,在刪除之前先計(jì)算要?jiǎng)h除的文件或者目錄大小浙垫,然后對(duì)比系統(tǒng)的磁盤空間刨仑,如果夠則按照上面的規(guī)則創(chuàng)建隱藏目錄,并備份夹姥,如果沒有足夠空間杉武,要提醒用戶沒有足夠的空間備份并提示是否放棄備份,如果用戶輸入yes辙售,則直接刪除文件或者目錄轻抱,如果輸入no,則提示未刪除旦部,然后退出腳本祈搜,示例:

#!/bin/bash
fileName=$1
now=`date +%Y%m%d%H%M`
f_size=`du -sk $1 |awk '{print $1}'`
disk_size=`LANG=en; df -k |grep -vi filesystem |awk '{print $4}' |sort -n |tail -n1`
big_filesystem=`LANG=en; df -k |grep -vi filesystem |sort -n -k4 |tail -n1 |awk '{print $NF}'`

if [ $f_size -lt $disk_size ]
then
   read -p "Are you sure delete the file or directory: $1 ? yes|no: " input
   if [ $input == "yes" ] || [ $input == "y" ]
   then
      mkdir -p $big_filesystem/.$now && rsync -aR $1 $big_filesystem/.$now/ && /bin/rm -rf $1
   elif [ $input == "no" ] || [ $input == "n" ]
   then
      exit 0
   else
      echo "Only input 'yes' or 'no'."
   fi
else
   echo "The disk size is not enough to backup the file: $1."
   read -p "Do you want to delete "$1"? yes|no: " input
   if [ $input == "yes" ] || [ $input == "y" ]
   then
       echo "It will delete "$1" after 5 seconds whitout backup."
       for i in `seq 1 5`; do echo -ne "."; sleep 1; done
     echo
       /bin/rm -rf $1
   elif [ $input == "no" ] || [ $input == "n" ]
   then
       echo "It will not delete $1."
       exit 0
   else
       echo "Only input 'yes' or 'no'."
   fi
fi

【腳本5】數(shù)字求和

編寫shell腳本,要求輸入一個(gè)數(shù)字士八,然后計(jì)算出從1到輸入數(shù)字的和容燕,要求,如果輸入的數(shù)字小于1婚度,則重新輸入蘸秘,直到輸入正確的數(shù)字為止,示例:

#!/bin/bash
while :
do
   read -p "Please enter a positive integer: " n
   if [ $n -lt 1 ]
   then
      echo "It can't be less than 1"
   else
      break
   fi
done

num=1
for i in `seq 2 $n`
do
   num=$[$num+$i]
done

echo $num

【腳本6】拷貝目錄

編寫shell腳本蝗茁,把/root/目錄下的所有目錄(只需要一級(jí))拷貝到/tmp/目錄下:

#!/bin/bash
cd /root/
list=(`ls`)

for i in ${list[@]}
do
   if [ -d $i ]
   then
       cp -r $i /tmp/
   fi
done

【腳本7】批量建立用戶

編寫shell腳本醋虏,批量建立用戶user_00, user_01, ... user_100并且所有用戶同屬于users組:

#!/bin/bash
group=`cat /etc/group |grep -o users`
if [ $group == "users" ]
then
    for i in `seq 0 100`
    do
      if [ $i -lt 10 ]
      then
          useradd -g users user_0$i
      else
          useradd -g users user_$i
      fi
    done
else
    echo "users group not found!"
    exit 1
fi

刪除以上腳本批量添加的用戶:

#!/bin/bash
for i in `seq 0 100`
do
   if [ $i -lt 10 ]
   then
       userdel -r user_0$i
   else
       userdel -r user_$i
   fi
done

【腳本8】每日生成一個(gè)文件

要求:請(qǐng)按照這樣的日期格式(xxxx-xx-xx)每日生成一個(gè)文件,例如今天生成的文件為)2017-07-05.log哮翘, 并且把磁盤的使用情況寫到到這個(gè)文件中颈嚼,(不用考慮cron,僅僅寫腳本即可)

#!/bin/bash
fileName=`date +%F`
c=`df -h`
echo "$c" > /root/$fileName.log

【腳本9】統(tǒng)計(jì)ip

有一個(gè)日志文件饭寺,日志片段:如下:

112.111.12.248 – [25/Sep/2013:16:08:31 +0800]formula-x.haotui.com “/seccode.php?update=0.5593110133088248″ 200″http://formula-x.haotui.com/registerbbs.php” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;)”
61.147.76.51 – [25/Sep/2013:16:08:31 +0800]xyzdiy.5d6d.com “/attachment.php?aid=4554&k=9ce51e2c376bc861603c7689d97c04a1&t=1334564048&fid=9&sid=zgohwYoLZq2qPW233ZIRsJiUeu22XqE8f49jY9mouRSoE71″ 301″http://xyzdiy.×××thread-1435-1-23.html” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)”

要求: 統(tǒng)計(jì)出每個(gè)IP的訪問量有多少阻课?

awk '{print $1}' 1.log |sort -n |uniq -c |sort -n

解釋:sort -n會(huì)按照數(shù)值而不是ASCII碼來排序awk截取出來的IP。然后uniq命令用于報(bào)告或忽略文件中的重復(fù)行佩研,加上-c選項(xiàng)后會(huì)在每列旁邊顯示該行重復(fù)出現(xiàn)的次數(shù)柑肴,在這一步就完成了統(tǒng)計(jì)。不過最后還得再讓sort -n排序一下uniq -c統(tǒng)計(jì)出來的結(jié)果旬薯。


【腳本10】統(tǒng)計(jì)內(nèi)存使用

寫一個(gè)腳本計(jì)算一下linux系統(tǒng)所有進(jìn)程占用內(nèi)存大小的和晰骑。

實(shí)現(xiàn)代碼:

#!/bin/bash
count=0
# 這個(gè)循環(huán)會(huì)遍歷出每個(gè)進(jìn)程占用的內(nèi)存大小
for i in `ps aux |awk '{print $6}' |grep -v 'RSS'`
do
   # 將遍歷出來的數(shù)字進(jìn)行累加
   count=$[$count+$i]
done

# 就得到所有進(jìn)程占用內(nèi)存大小的和了
echo "$count/kb"

也可以使用awk 一條命令計(jì)算:

ps aux |grep -v 'RSS TTY' |awk '{sum=sum+$6};END{print sum}'

解釋:grep -v是忽略 'RSS TTY' 所存在的那一行,后面的awk聲明了一個(gè)變量sum,sum將前面命令列出來的數(shù)字進(jìn)行累加硕舆,END之后就將累加后的sum打印出來秽荞,就得到所有進(jìn)程占用內(nèi)存大小的和了。


【腳本11】簡(jiǎn)單的監(jiān)控腳本

設(shè)計(jì)一個(gè)簡(jiǎn)單的腳本抚官,監(jiān)控遠(yuǎn)程的一臺(tái)機(jī)器(假設(shè)ip為123.23.11.21)的存活狀態(tài)扬跋,當(dāng)發(fā)現(xiàn)宕機(jī)時(shí)發(fā)一封郵件給你自己。

#!/bin/bash
ip="123.23.11.21"
email="user@example"

while 1
do
  ping -c10 $ip > /dev/null 2>/dev/null
  if [ $? != "0" ]
  then
       # 調(diào)用一個(gè)用于發(fā)郵件的腳本
     python /usr/local/sbin/mail.py $email "$ip down" "$ip is down"
  fi
  sleep 30
done

mail.py 腳本代碼:

#!/usr/bin/env python
#-*- coding: UTF-8 -*-
import os,sys
reload(sys)
sys.setdefaultencoding('utf8')
import getopt
import smtplib
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from  subprocess import *
def sendqqmail(username,password,mailfrom,mailto,subject,content):
    # 郵箱的服務(wù)地址
    gserver = 'smtp.qq.com'
    gport = 25
    try:
        msg = MIMEText(unicode(content).encode('utf-8'))
        msg['from'] = mailfrom
        msg['to'] = mailto
        msg['Reply-To'] = mailfrom
        msg['Subject'] = subject
        smtp = smtplib.SMTP(gserver, gport)
        smtp.set_debuglevel(0)
        smtp.ehlo()
        smtp.login(username,password)
        smtp.sendmail(mailfrom, mailto, msg.as_string())
        smtp.close()
    except Exception,err:
        print "Send mail failed. Error: %s" % err
def main():
    to=sys.argv[1]
    subject=sys.argv[2]
    content=sys.argv[3]
    #定義QQ郵箱的賬號(hào)和密碼凌节,你需要修改成你自己的賬號(hào)和密碼
    sendqqmail('1234567@qq.com','aaaaaaaaaa','1234567@qq.com',to,subject,content)
if __name__ == "__main__":
    main()

#####腳本使用說明######
#1\. 首先定義好腳本中的郵箱賬號(hào)和密碼
#2\. 腳本執(zhí)行命令為:python mail.py 目標(biāo)郵箱 "郵件主題" "郵件內(nèi)容"

【腳本12】批量更改文件名

需求:

  • 找到/123目錄下所有后綴名為.txt的文件
  • 批量修改.txt為.txt.bak
  • 把所有.bak文件打包壓縮為123.tar.gz
  • 批量還原文件的名字钦听,即把增加的.bak再刪除

代碼:

#!/bin/bash
now=`date +%F_%T`
mkdir /tmp/123_$now
for txt in `ls /123/*.txt`
do
  mv $txt $txt.bak
  for f in $txt
  do
    cp $txt.bak /tmp/123_$now
  done
done

cd /tmp/
tar czf 123.tar.gz 123_$now/

for txt in `ls /123/*.txt.bak`
do
  name=`echo $txt |awk -F '.' '{OFS="."} {print $1,$2}'`
  mv $txt $name
done

【腳本13】監(jiān)控80端口

需求:
寫一個(gè)腳本,判斷本機(jī)的80端口(假如服務(wù)為httpd)是否開啟著倍奢,如果開啟著什么都不做朴上,如果發(fā)現(xiàn)端口不存在,那么重啟一下httpd服務(wù)卒煞,并發(fā)郵件通知你自己痪宰。腳本寫好后,可以每一分鐘執(zhí)行一次畔裕,也可以寫一個(gè)死循環(huán)的腳本衣撬,30s檢測(cè)一次。
發(fā)郵件的腳本參考【腳本11】的示例代碼扮饶。
代碼:

#!/bin/bash
email="user@example.com"
if netstat -lntp |grep ':80' |grep 'httpd'
then
   echo "80 port no problem"
   exit
else
   /usr/local/apache2.4/bin/apachectl restart
   python mail.py $email "check_80port" "The 80 port is down."
   n=`ps aux |grep httpd|grep -cv grep`

   if [ $n -eq 0 ]
   then
      /usr/local/apache2/bin/apachectl start 2>/tmp/apache_start.err
   fi

   if [ -s /tmp/apache_start.err ]
     then
      python mail.py  $mail 'apache_start_error' `cat /tmp/apache_start.err`
   fi
fi

【腳本14】備份數(shù)據(jù)庫

需求:

設(shè)計(jì)一個(gè)shell腳本來備份數(shù)據(jù)庫具练,首先在本地服務(wù)器上保存一份數(shù)據(jù),然后再遠(yuǎn)程拷貝一份贴届,本地保存一周的數(shù)據(jù)靠粪,遠(yuǎn)程保存一個(gè)月。

假定毫蚓,我們知道m(xù)ysql root賬號(hào)的密碼,要備份的庫為discuz昔善,本地備份目錄為/bak/mysql, 遠(yuǎn)程服務(wù)器ip為192.168.123.30元潘,遠(yuǎn)程提供了一個(gè)rsync服務(wù),備份的地址是 192.168.123.30::backup . 寫完腳本后君仆,需要加入到cron中翩概,每天凌晨3點(diǎn)執(zhí)行。
腳本代碼:

#!/bin/bash
PATH=$PATHi:/usr/local/mysql/bin
week=`date +%w`
today=`date +d`
passwd="123456"
backdir="/data/mysql"
r_backupIP="192.168.123.30::backup"

exec 1>/var/log/mysqlbak.log 2>/var/log/mysqlbak.log
echo "mysql backup begin at `date +%F %T`."

# 本地備份
mysqldump -uroot -p$passwd --default-character-set=utf8 discuz >$backdir/$week.sql
# 同步備份到遠(yuǎn)程機(jī)器
rsync -az $backdir/$week.sql $r_backupIP/$today.sql

echo "mysql backup end at `date +%F %T`."

然后加入cron
0 3 * * * /bin/bash /usr/local/sbin/mysqlbak.sh


【腳本15】自動(dòng)重啟php-fpm服務(wù)

服務(wù)器上跑的是LNMP環(huán)境,近期總是有502現(xiàn)象。502為網(wǎng)站訪問的狀態(tài)碼怯疤,200正常呀伙,502錯(cuò)誤是nginx最為普通的錯(cuò)誤狀態(tài)碼。由于502只是暫時(shí)的顽悼,并且只要一重啟php-fpm服務(wù)則502消失,但不重啟的話胀茵,則會(huì)一直持續(xù)很長(zhǎng)時(shí)間吐句。所以有必要寫一個(gè)監(jiān)控腳本胁后,監(jiān)控訪問日志的狀態(tài)碼,一旦發(fā)生502嗦枢,則自動(dòng)重啟一下php-fpm攀芯。

我們?cè)O(shè)定:

  1. access_log /data/log/access.log
  2. 腳本死循環(huán),每10s檢測(cè)一次(假設(shè)每10s鐘的日志條數(shù)為300左右)
  3. 重啟php-fpm的方法是 /etc/init.d/php-fpm restart

腳本代碼:

#!/bin/bash
access_log="/data/log/access.log"
N=10
while :
do
   # 因?yàn)?0秒大概產(chǎn)生300條日志記錄
   tail -n300 $access_log > /tmp/log
   # 拿出log中包含502的日志行數(shù)
   n_502=`grep -c "502" /tmp/log`
   # 如果行數(shù)大于10
   if [ $n_502 -ge $N ]
   then
      # 就記錄一下系統(tǒng)狀態(tài)
      top -bn1 > /tmp/`date +%H%M%S`-top.log
      vmstat 1 5 > /tmp/`date +%H%M%S`-vm.log
      # 然后才重啟服務(wù)文虏,并把錯(cuò)誤信息重定向
      /etc/init.d/php-fpm restart 2> /dev/null
      # 重啟php-fpm服務(wù)后侣诺,應(yīng)先暫緩1分鐘,而后繼續(xù)每隔10s檢測(cè)一次
      sleep(60)
   fi
   sleep(10)
done

【腳本16】文本替換

將memcached里的數(shù)據(jù)導(dǎo)出到文件中氧秘,然后再導(dǎo)入memcached里卻發(fā)現(xiàn)數(shù)據(jù)過期了紧武,這是因?yàn)閷?dǎo)出的數(shù)據(jù)是帶有一個(gè)時(shí)間戳的,這個(gè)時(shí)間戳就是該條數(shù)據(jù)過期的時(shí)間點(diǎn)敏储,如果當(dāng)前時(shí)間已經(jīng)超過該時(shí)間戳阻星,那么是導(dǎo)入不進(jìn)去的。不過可以修改文件中的時(shí)間戳來保證導(dǎo)入時(shí)數(shù)據(jù)的有效期已添⊥谆可以寫一個(gè)簡(jiǎn)單的腳本批量替換這些文件中的時(shí)間戳:

#!/bin/bash
hour=`date -d "+1 hour" +%s`  # 一個(gè)小時(shí)之后的時(shí)間戳
data_time=`cat data.txt |grep add |awk '{print $4}' |sort -n |uniq`
for i in $data_time
do
   sed -i "s/$i/$hour/g" `grep $i -rl /root/data.txt`
done

【腳本17】啟動(dòng)容器

docker每次關(guān)閉都會(huì)連帶著將運(yùn)行中的容器關(guān)閉,所以每次啟動(dòng)docker后都需要逐個(gè)去啟動(dòng)容器更舞,很麻煩畦幢,由于是實(shí)驗(yàn)用的虛擬機(jī)不是線上的機(jī)器,所以就直接寫了一個(gè)很簡(jiǎn)單的循環(huán)來啟動(dòng)容器:

#!/bin/bash
/usr/bin/systemctl start docker

for i in `docker ps -a |grep 'Exited' |awk '{print $1}'`
do
  /usr/bin/docker start $i
done

【腳本18】刪除文本中的字母

要求:把一個(gè)文本文檔的前5行中包含字母的行刪除掉缆蝉,同時(shí)把6到10行中的全部字母刪除掉宇葱。

參考答案:假設(shè)文本名字叫做1.txt,并且文本行數(shù)大于10刊头,腳本如下:

#!/bin/bash

## 先獲取該文本的行數(shù)
rows=`wc -l 1.txt |awk '{print $1}'`

## 對(duì)前5行進(jìn)行處理
for i in `seq 1 5`
do
  ## 使用sed把每一行的內(nèi)容賦值給變量
  row=`sed -n "$i"p 1.txt`
  ## 用grep 判定是否匹配字母黍瞧,-v取反,-q不輸出內(nèi)容
  if echo $row |grep -vq '[a-zA-Z]'
  then
     echo $row
  fi
done

## 對(duì)6-10行做刪除字母處理
for i in `seq 6 10`
do
  row=`sed -n "$i"p 1.txt`
  echo $row |sed 's/[a-zA-Z]//g'
done

## 剩余的直接輸出
for i in `seq 11 $rows`
do
  sed -n "$i"p 1.txt
done

##若想把更改內(nèi)容寫入到1.txt原杂,還需要把以上內(nèi)容重定向到一個(gè)文本中印颤,然后刪除1.txt,再把剛剛重定向的文件更名為1.txt

【腳本19】查找字母數(shù)小于6的單詞

用shell打印下面這句話中字母數(shù)小于6的單詞穿肄。
Bash also interprets a number of multi-character options.

腳本如下:

#!/bin/bash
for s in Bash also interprets a number of multi-character options
do
  n=`echo $s |wc -c`
  if [ $n -lt 6 ]
  then
     echo $s
  fi
done

【腳本20】輸入數(shù)字執(zhí)行對(duì)應(yīng)命令

寫一個(gè)腳本實(shí)現(xiàn)如下功能: 輸入一個(gè)數(shù)字年局,然后運(yùn)行對(duì)應(yīng)的一個(gè)命令。顯示命令如下:

cmd meau* 1—date 2–ls 3–who 4–pwd

當(dāng)輸入1時(shí)咸产,會(huì)運(yùn)行date, 輸入2時(shí)運(yùn)行l(wèi)s, 依此類推矢否。

實(shí)現(xiàn)腳本如下:

#!/bin/bash
echo "*cmd meau**  1—date 2–ls 3–who 4–pwd"

read -p "please input a number 1-4: " n
case $n in
   1)
      date
   ;;
   2)
      ls
   ;;
   3)
      who
   ;;
   4)
      pwd
   ;;
   *)
      echo "Please input a number: 1-4"
   ;;
esac

【腳本21】批量創(chuàng)建用戶并設(shè)置密碼

用shell腳本實(shí)現(xiàn)如下需求:
添加user_00 – user_09 10個(gè)用戶,并且給他們?cè)O(shè)置一個(gè)隨機(jī)密碼脑溢,密碼要求10位包含大小寫字母以及數(shù)字僵朗,注意需要把每個(gè)用戶的密碼記錄到一個(gè)日志文件里。

提示:

  1. 隨機(jī)密碼使用命令 mkpasswd
  2. 在腳本中給用戶設(shè)置密碼,可以使用echo 然后管道passwd命令

實(shí)現(xiàn)腳本如下:

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

【腳本22】監(jiān)控httpd進(jìn)程

在服務(wù)器上衣迷,寫一個(gè)監(jiān)控腳本畏鼓。

  1. 每隔10s去檢測(cè)一次服務(wù)器上的httpd進(jìn)程數(shù),如果大于等于500的時(shí)候壶谒,就需要自動(dòng)重啟一下apache服務(wù)云矫,并檢測(cè)啟動(dòng)是否成功?
  2. 若沒有正常啟動(dòng)還需再一次啟動(dòng)汗菜,最大不成功數(shù)超過5次則需要理解發(fā)郵件通知管理員让禀,并且以后不需要再檢測(cè)!
  3. 如果啟動(dòng)成功后陨界,1分鐘后再次檢測(cè)httpd進(jìn)程數(shù)巡揍,若正常則重復(fù)之前操作(每隔10s檢測(cè)一次),若還是大于等于500菌瘪,那放棄重啟并需要發(fā)郵件給管理員腮敌,然后自動(dòng)退出該腳本。假設(shè)其中發(fā)郵件腳本為mail.py

實(shí)現(xiàn)腳本如下:

#!/bin/bash

check_service(){
  n=0
  for i in `seq 1 5`
  do
    # apachectl命令所在路徑
    /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的內(nèi)容參考https://coding.net/u/aminglinux/p/aminglinux-book/git/blob/master/D22Z/mail.py
    python mail.py "123@qq.com" "httpd service down" `cat /tmp/apache.err`
    exit
  fi
}

while : 
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 mail.py "123@qq.com" "httpd service somth wrong" "the httpd process is budy."
        exit
     fi
  fi
  sleep 10
done

【腳本23】封ip

需求: 根據(jù)web服務(wù)器上的訪問日志俏扩,把一些請(qǐng)求量非常高的ip給拒絕掉糜工!

分析: 我們要做的,不僅是要找到哪些ip請(qǐng)求量不合法录淡,并且還要每隔一段時(shí)間把之前封掉的ip(若不再繼續(xù)請(qǐng)求了)給解封捌木。 所以該腳本的關(guān)鍵點(diǎn)在于定一個(gè)合適的時(shí)間段和閾值。

比如嫉戚, 我們可以每一分鐘去查看一下日志刨裆,把上一分鐘的日志給過濾出來分析,并且只要請(qǐng)求的ip數(shù)量超過100次那么就直接封掉彬檀。 而解封的時(shí)間又規(guī)定為每半小時(shí)分析一次帆啃,把幾乎沒有請(qǐng)求量的ip給解封!

參考日志文件片段:

157.55.39.107 [20/Mar/2015:00:01:24 +0800] www.aminglinux.com “/bbs/thread-5622-3-1.html” 200 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”
61.240.150.37 [20/Mar/2015:00:01:34 +0800] www.aminglinux.com “/bbs/search.php?mod=forum&srchtxt=LNMP&formhash=8f0c7da9&searchsubmit=true&source=hotsearch” 200 “-” “Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)”

腳本實(shí)現(xiàn)如下:

#!/bin/bash
## 日志文件路徑
log_file="/home/logs/client/access.log"
## 當(dāng)前時(shí)間減一分鐘的時(shí)間
d1=`date -d "-1 minute" +%H:%M`
## 當(dāng)前時(shí)間的分鐘段
d2=`date +%M`
## iptables命令所在的路徑
ipt="/sbin/iptables"
## 用于存儲(chǔ)訪問日志里的ip
ips="/tmp/ips.txt"

## 封ip
block(){
   ## 把日志文件中的ip過濾出來凤覆,去掉重復(fù)的ip链瓦,并統(tǒng)計(jì)ip的重復(fù)次數(shù)以及對(duì)ip進(jìn)行排序,最后將結(jié)果寫到一個(gè)文件中
   grep "$d1:" $log_file |awk '{print $1}' |sort -n |uniq -c |sort -n > $ips
   ## 將文件里重復(fù)次數(shù)大于100的ip迭代出來
   for ip in `awk '$1 > 100 {print $2}' $ips`
   do
      ## 通過防火墻規(guī)則對(duì)這些ip進(jìn)行封禁
      $ipt -I INPUT -p -tcp --dport 80 -s $ip -j REJECT
      ## 將已經(jīng)封禁的ip輸出到一個(gè)文件里存儲(chǔ)
      echo "`date +%F-%T` $ip" >> /tmp/badip.txt
   done
}

## 解封ip
unblock(){
   ## 將流量小于15的規(guī)則索引過濾出來
   for i in `$ipt -nvL --line-number |grep '0.0.0.0/0' |awk '$2 < 15 {print $1}' |sort -nr`
   do
      ## 通過索引來刪除規(guī)則
      $ipt -D INPUT $i
   done
   ## 清空規(guī)則中的數(shù)據(jù)包計(jì)算器和字節(jié)計(jì)數(shù)器
   $ipt -Z
}

## 為整點(diǎn)或30分鐘就是過了半個(gè)小時(shí)盯桦,就需要再進(jìn)行分析
if [ $d2 == "00" ] || [ $d2 == "30" ]
then
   unblock
   block
else
   block
fi

【腳本24】部署前端項(xiàng)目

最近做了一個(gè)web前端的項(xiàng)目,需要編寫一個(gè)腳本完成項(xiàng)目的上線渤刃。

腳本實(shí)現(xiàn)如下:

#!/bin/bash

#
# 使用方法:
# mmall:front_deploy.sh mmall-fe
# admin:front_deploy.sh admin-fe
#

GIT_HOME=/developer/git-repository/   # 從git倉庫拉取下來的源碼的存放路徑
DEST_PATH=/product/frontend/    # 項(xiàng)目打包后的發(fā)布路徑

# cd dir
if [ ! -n "$1" ]
then
    echo -e "請(qǐng)輸入要發(fā)布的項(xiàng)目拥峦!"
    exit
fi 

if [ $1 = "mmall-fe" ]
then
    echo -e "===========Enter mall-fe============="
    cd $GIT_HOME$1
elif [ $1 = "admin-fe" ]
then
    echo -e "===========Enter mall-fe============="
    cd $GIT_HOME$1
else 
    echo -e "輸入的項(xiàng)目名沒有找到!"
    exit
fi

# clear git dist
echo -e "===========Clear Git Dist============="
rm -rf ./dist

# git操作
echo -e "===========git checkout master============="
git checkout master

echo -e "===========git pull============="
git pull

# npm install
echo -e "===========npm install============="
npm install --registry=https://registry.npm.taobao.org

# npm run dist
echo -e "===========npm run dist============="
npm run dist

if [ -d "./dist" ]
then
    # backup dest
    echo -e "===========dest backup============="
    mv $DEST_PATH$1/dist $DEST_PATH$1/dist.bak

    # copy
    echo -e "===========copy============="
    cp -R ./dist $DEST_PATH$1

    # echo result
    echo -e "===========Deploy Success============="
else
    echo -e "===========Deploy Error============="
fi

【腳本25】找規(guī)律打印數(shù)字

請(qǐng)?jiān)敿?xì)查看如下幾個(gè)數(shù)字的規(guī)律卖子,并使用shell腳本輸出后面的十個(gè)數(shù)字略号。

10 31 53 77 105 141 …….

試題解析:
我想大多數(shù)人都會(huì)去比較這些數(shù)字的差值:

10  31  53  77  105  141
21   22   24   28   36

但是這個(gè)差值看,并沒有什么規(guī)律,而我們?cè)僮屑?xì)看的時(shí)候玄柠,發(fā)現(xiàn)這個(gè)差值的差值是有規(guī)律的:

10  31  53  77  105  141
21   22   24   28   36
1      2     4     8

腳本實(shí)現(xiàn):

#! /bin/bash
x=21
m=10
echo $m
for i in `seq 0 14`; do
 j=$[2**$i]
 m=$[$m+$x]
 echo $m
 x=$[$x+$j]
done

【腳本26】統(tǒng)計(jì)普通用戶

寫個(gè)shell突梦,看看你的Linux系統(tǒng)中是否有自定義用戶(普通用戶),若是有羽利,一共有幾個(gè)宫患?

假設(shè)所有普通用戶都是uid大于1000的

腳本實(shí)現(xiàn):

#!/bin/bash
 n=`awk -F ':' '$3>1000' /etc/passwd|wc -l`
 if [ $n -gt 0 ]
 then
     echo "There are $n common users."
 else
     echo "No common users."
 fi

【腳本27】監(jiān)控磁盤使用率

寫一個(gè)shell腳本,檢測(cè)所有磁盤分區(qū)使用率和inode使用率并記錄到以當(dāng)天日期為命名的日志文件里这弧,當(dāng)發(fā)現(xiàn)某個(gè)分區(qū)容量或者inode使用量大于85%時(shí)娃闲,發(fā)郵件通知你自己。

思路:就是先df -h 然后過濾出已使用的那一列匾浪,然后再想辦法過濾出百分比的整數(shù)部分皇帮,然后和85去比較,同理蛋辈,inode也是一樣的思路属拾。

實(shí)現(xiàn)代碼:

#!/bin/bash
## This script is for record Filesystem Use%,IUse% everyday and send alert mail when % is more than 85%.

log=/var/log/disk/`date +%F`.log
date +'%F %T' > $log
df -h >> $log
echo >> $log
df -i >> $log

for i in `df -h|grep -v 'Use%'|sed 's/%//'|awk '{print $5}'`; do
    if [ $i -gt 85 ]; then
        use=`df -h|grep -v 'Use%'|sed 's/%//'|awk '$5=='$i' {print $1,$5}'`
        echo "$use" >> use
    fi
done
if [ -e use ]; then

   ##這里可以使用咱們之前介紹的mail.py發(fā)郵件
    mail -s "Filesystem Use% check" root@localhost < use
    rm -rf use
fi

for j in `df -i|grep -v 'IUse%'|sed 's/%//'|awk '{print $5}'`; do
    if [ $j -gt 85 ]; then
        iuse=`df -i|grep -v 'IUse%'|sed 's/%//'|awk '$5=='$j' {print $1,$5}'`
        echo "$iuse" >> iuse
    fi
done
if [ -e iuse ]; then
    mail -s "Filesystem IUse% check" root@localhost < iuse
    rm -rf iuse
fi

思路:

  1. df -h、df -i 記錄磁盤分區(qū)使用率和inode使用率冷溶,date +%F 日志名格式
  2. 取出使用率(第5列)百分比序列渐白,for循環(huán)逐一與85比較,大于85則記錄到新文件里挂洛,當(dāng)for循環(huán)結(jié)束后礼预,匯總超過85的一并發(fā)送郵件(郵箱服務(wù)因未搭建,發(fā)送本地root賬戶)虏劲。

此腳本正確運(yùn)行前提:

  • 該系統(tǒng)沒有邏輯卷的情況下使用托酸,因?yàn)檫壿嬀韉f -h、df -i 時(shí)柒巫,使用率百分比是在第4列励堡,而不是第5列。如有邏輯卷堡掏,則會(huì)漏統(tǒng)計(jì)邏輯卷使用情況应结。

【腳本28】獲取文件列表

有一臺(tái)服務(wù)器作為web應(yīng)用,有一個(gè)目錄(/data/web/attachment)不定時(shí)地會(huì)被用戶上傳新的文件泉唁,但是不知道什么時(shí)候會(huì)上傳鹅龄。所以,需要我們每5分鐘做一次檢測(cè)是否有新文件生成亭畜。

請(qǐng)寫一個(gè)shell腳本去完成檢測(cè)扮休。檢測(cè)完成后若是有新文件,還需要將新文件的列表輸出到一個(gè)按年拴鸵、月玷坠、日蜗搔、時(shí)、分為名字的日志里八堡。請(qǐng)不要想的太復(fù)雜樟凄,核心命令只有一個(gè) find /data/web/attachment -mmin -5

思路: 每5分鐘檢測(cè)一次,那肯定需要有一個(gè)計(jì)劃任務(wù)兄渺,每5分鐘去執(zhí)行一次缝龄。腳本檢測(cè)的時(shí)候,就是使用find命令查找5分鐘內(nèi)有過更新的文件溶耘,若是有更新二拐,那這個(gè)命令會(huì)輸出東西,否則是沒有輸出的凳兵。固百新,我們可以把輸出結(jié)果的行數(shù)作為比較對(duì)象,看看它是否大于0庐扫。

實(shí)現(xiàn)代碼:

#!/bin/bash
d=`date -d "-5 min" +%Y%m%d%H%M`
basedir=/data/web/attachment
find $basedir/ -type f  -mmin -5 > /tmp/newf.txt
n=`wc -l /tmp/newf.txt`
if [ $n -gt 0 ]; then
    /bin/mv /tmp/newf.txt /tmp/$d

fi

【腳本29】統(tǒng)計(jì)常用命令

寫一個(gè)shell腳本來看看你使用最多的命令是哪些饭望,列出你最常用的命令top10。

思路:我們要用到一個(gè)文件就是.bash_history形庭,然后再去sort铅辞、uniq,剩下的就不用我多說了吧萨醒。很簡(jiǎn)單一個(gè)shell斟珊。

一條命令即可:
sort /root/.bash_history |uniq -c |sort -nr |head


【腳本30】統(tǒng)計(jì)日志大小

假如我們需要每小時(shí)都去執(zhí)行你寫的腳本。在腳本中實(shí)現(xiàn)這樣的功能富纸,當(dāng)時(shí)間是0點(diǎn)和12點(diǎn)時(shí)囤踩,需要將目錄/data/log/下的文件全部清空,注意只能清空文件內(nèi)容而不能刪除文件晓褪。而其他時(shí)間只需要統(tǒng)計(jì)一下每個(gè)文件的大小堵漱,一個(gè)文件一行,輸出到一個(gè)按日期和時(shí)間為名字的日志里涣仿。 需要考慮/data/log/目錄下的二級(jí)勤庐、三級(jí)、… 等子目錄里面的文件好港。

實(shí)現(xiàn)代碼:

#!/bin/bash

logdir="/data/log"
t=`date +%H`
d=`date +%F-%H`
[ -d /tmp/log_size ] || mkdir /tmp/log_size
for log in `find $logdir -type f`
do
    if [ $t == "0" ] || [ $t == "12" ]
    then
    true > $log
    else
    du -sh $log >>/tmp/log_size/$d
    fi
done

【腳本31】統(tǒng)計(jì)數(shù)字并求和

計(jì)算文檔a.txt中每一行中出現(xiàn)的數(shù)字個(gè)數(shù)并且要計(jì)算一下整個(gè)文檔中一共出現(xiàn)了幾個(gè)數(shù)字愉镰。例如a.txt內(nèi)容如下:

12aa*lkjskdj
alskdflkskdjflkjj

我們腳本名字為 ncount.sh, 運(yùn)行它時(shí):

bash ncount.sh a.txt

輸入結(jié)果應(yīng)該為:

2
0
sum:2

實(shí)現(xiàn)代碼:

#!/bin/bash

n=`wc -l a.txt|awk '{print $1}'`
sum=0
for i in `seq 1 $n`
do
    line=`sed -n "$i"p a.txt`
    n_n=`echo -n $line|sed 's/[^0-9]//g'|wc -c`
    echo line $i number: $n_n
    sum=$[$sum+$n_n]
done

echo sum is $sum

【腳本32】檢測(cè)文件改動(dòng)

有兩臺(tái)Linux服務(wù)器A和B,假如A可以直接ssh到B钧汹,不用輸入密碼岛杀。A和B都有一個(gè)目錄叫做/data/web/ 這下面有很多文件,當(dāng)然我們不知道具體有幾層子目錄崭孤,假若之前A和B上該目錄下的文件都是一模一樣的类嗤。但現(xiàn)在不確定是否一致了。固需要我們寫一個(gè)腳本實(shí)現(xiàn)這樣的功能辨宠,檢測(cè)A機(jī)器和B機(jī)器/data/web/目錄下文件的異同遗锣,我們以A機(jī)器上的文件作為標(biāo)準(zhǔn)。比如嗤形,假若B機(jī)器少了一個(gè)a.txt文件精偿,那我們應(yīng)該能夠檢測(cè)出來,或者B機(jī)器上的b.txt文件有過改動(dòng)赋兵,我們也應(yīng)該能夠檢測(cè)出來(B機(jī)器上多了文件我們不用考慮)笔咽。

提示: 使用核心命令 md5sum a.txt 算出md5值,去和B機(jī)器上的比較霹期。

實(shí)現(xiàn)代碼:

#!/bin/bash
#假設(shè)A機(jī)器到B機(jī)器已經(jīng)做了無密碼登錄設(shè)置
dir=/data/web
##假設(shè)B機(jī)器的IP為192.168.0.100
B_ip=192.168.0.100
find $dir -type f |xargs md5sum >/tmp/md5.txt
ssh $B_ip "find $dir -type f |xargs md5sum >/tmp/md5_b.txt"
scp $B_ip:/tmp/md5_b.txt /tmp
for f in `awk '{print $2}' /tmp/md5.txt`
do
    if grep -q "$f" /tmp/md5_b.txt
    then
        md5_a=`grep $f /tmp/md5.txt|awk '{print $1}'`
        md5_b=`grep $f /tmp/md5_b.txt|awk '{print $1}'`
        if [ $md5_a != $md5_b ]
        then
             echo "$f changed."
        fi
    else
        echo "$f deleted. "
    fi
done

【腳本33】統(tǒng)計(jì)網(wǎng)卡流量

寫一個(gè)腳本,檢測(cè)你的網(wǎng)絡(luò)流量叶组,并記錄到一個(gè)日志里。需要按照如下格式历造,并且一分鐘統(tǒng)計(jì)一次(只需要統(tǒng)計(jì)外網(wǎng)網(wǎng)卡甩十,假設(shè)網(wǎng)卡名字為eth0):

2017-08-04 01:11
eth0 input: 1000bps
eth0 output : 200000bps
################
2017-08-04 01:12
eth0 input: 1000bps
eth0 output : 200000bps

提示:使用sar -n DEV 1 59 這樣可以統(tǒng)計(jì)一分鐘的平均網(wǎng)卡流量,只需要最后面的平均值吭产。另外侣监,注意換算一下,1byt=8bit

實(shí)現(xiàn)代碼:

#!/bin/bash

while :
do
    LANG=en
    DATE=`date +"%Y-%m-%d %H:%M"`
    LOG_PATH=/tmp/traffic_check/`date +%Y%m`
    LOG_FILE=$LOG_PATH/traffic_check_`date +%d`.log
    [ -d $LOG_PATH ] || mkdir -p $LOG_PATH
    echo " $DATE" >> $LOG_FILE
    sar -n DEV 1 59|grep Average|grep eth0 \ 
    |awk '{print "\n",$2,"\t","input:",$5*1000*8,"bps", \
    "\t","\n",$2,"\t","output:",$6*1000*8,"bps" }' \ 
    >> $LOG_FILE
    echo "#####################" >> $LOG_FILE
done

【腳本34】系統(tǒng)-批量殺進(jìn)程

今天發(fā)現(xiàn)網(wǎng)站訪問超級(jí)慢臣淤,top看如下:


101個(gè)shell腳本

有很多sh進(jìn)程橄霉,再ps查看:


101個(gè)shell腳本

這個(gè)腳本,運(yùn)行很慢邑蒋,因?yàn)橹贫薱ron姓蜂,上一次還沒有運(yùn)行完,又有了新的運(yùn)行任務(wù)寺董。太多肯定會(huì)導(dǎo)致系統(tǒng)負(fù)載升高覆糟。當(dāng)務(wù)之急就是先把這些在跑的給kill掉。那么我們可以使用一條命令遮咖,直接殺死所有的sh滩字。

命令如下:

ps aux |grep clearmem.sh |grep -v grep|awk '{print $2}'|xargs kill

【腳本35】判斷是否開啟80端口

寫一個(gè)腳本判斷你的Linux服務(wù)器里是否開啟web服務(wù)?(監(jiān)聽80端口)如果開啟了御吞,請(qǐng)判斷出跑的是什么服務(wù)麦箍,是httpd呢還是nginx又或者是其他的什么?

實(shí)現(xiàn)代碼:

#!/bin/bash
 port=`netstat -lnp | grep 80`
 if [ -z "port" ]; then
     echo "not start service.";
     exit;
 fi
 web_server=`echo $port | awk -F'/' '{print $2}'|awk -F : '{print $1}'` 
case $web_server in
   httpd ) 
       echo "apache server."
   ;;
   nginx )
       echo "nginx server."
   ;;
   * )
       echo "other server."
   ;; 
esac

【腳本36】監(jiān)控mysql服務(wù)

假設(shè)陶珠,當(dāng)前MySQL服務(wù)的root密碼為123456沸伏,寫腳本檢測(cè)MySQL服務(wù)是否正常(比如,可以正常進(jìn)入mysql執(zhí)行show processlist)女器,并檢測(cè)一下當(dāng)前的MySQL服務(wù)是主還是從,如果是從栗竖,請(qǐng)判斷它的主從服務(wù)是否異常。如果是主渠啤,則不需要做什么狐肢。

實(shí)現(xiàn)代碼:

#!/bin/bash
Mysql_c="mysql -uroot -p123456"
$Mysql_c -e "show processlist" >/tmp/mysql_pro.log 2>/tmp/mysql_log.err
n=`wc -l /tmp/mysql_log.err|awk '{print $1}'`

if [ $n -gt 0 ]
then
    echo "mysql service sth wrong."
else

    $Mysql_c -e "show slave status\G" >/tmp/mysql_s.log
    n1=`wc -l /tmp/mysql_s.log|awk '{print $1}'`

    if [ $n1 -gt 0 ]
    then
        y1=`grep 'Slave_IO_Running:' /tmp/mysql_s.log|awk -F : '{print $2}'|sed 's/ //g'`
        y2=`grep 'Slave_SQL_Running:' /tmp/mysql_s.log|awk -F : '{print $2}'|sed 's/ //g'`

        if [ $y1 == "Yes" ] && [ $y2 == "Yes" ]
        then
            echo "slave status good."
        else
            echo "slave down."
        fi
    fi
fi

【腳本37】帶選項(xiàng)的用戶腳本

要求如下:

  1. 只支持三個(gè)選項(xiàng) ‘–del’ ‘–add’ –help輸入其他選項(xiàng)報(bào)錯(cuò)。
  2. 使用‘–add’需要驗(yàn)證用戶名是否存在沥曹,存在則反饋存在份名。且不添加。 不存在則創(chuàng)建該用戶妓美,切>添加與該用戶名相同的密碼僵腺。并且反饋。
  3. 使用‘–del’ 需要驗(yàn)證用戶名是否存在壶栋,存在則刪除用戶及其家目錄辰如。不存在則反饋該用戶不存>在。
  4. –help 選項(xiàng)反饋出使用方法
  5. 支持以委刘,分隔 一次刪除多個(gè)或者添加多個(gè)用戶丧没。
  6. 能用echo $? 檢測(cè)腳本執(zhí)行情況 成功刪除或者添加為0,報(bào)錯(cuò)信息為其他數(shù)字。
  7. 能以锡移,分割呕童。一次性添加或者 刪除多個(gè)用戶。 例如 adddel.sh –add user1,user2,user3…….
  8. 不允許存在明顯bug淆珊。

代碼參考:

#!/bin/bash
#written by aming.

if [ $# -eq 0 -o $# -gt 2 ]
then
    echo "use $0 --add username or $0 --del username or $0 --help."
    exit 1
fi

case $1 in
    --add)
        n=0
        for u in `echo $2|sed 's/,/ /g'`; do
            if awk -F: '{print $1}' /etc/passwd |grep -qw "$u"
            then
               echo "The user $u exist."
            else
                useradd $u
                echo -e "$u\n$u"|passwd $u >/dev/null 2>&1
                echo "The user $u added successfully."
                n=$[$n+1]
            fi
        done

        if [ $n -eq 0 ]; then
            exit 2
        fi
        ;;

    --del)
        n=0
        for u in `echo $2|sed 's/,/ /g'`; do
            if awk -F: '{print $1}' /etc/passwd|grep -qw "$u"
            then
               userdel -r $u
                echo "The user $u deleted successfully."
                n=$[$n+1]
            else
                echo "The user $u not exist."
            fi
        done

        if [ $n -eq 0 ]; then
                exit 3
        fi
        ;;

    --help)
        echo -e "--add can add user,and the passwd is the same as username.     
    It can add multiuser such as --add user1,user2,user3..."
        echo "--del cat delete user.It can delete user such as --del user1,user2,user3..."
        ;;

    *)
        echo "use $0 --add username or $0 --del username or $0 --help."
        exit 1
        ;;
esac

【腳本38】被3整除

寫一個(gè)腳本: 計(jì)算100以內(nèi)所有能被3整除的正整數(shù)的和

代碼參考:

#!/bin/bash
sum=0
for i in {1..100};do
    if [ $[$i%3] -eq 0 ];then
    sum=$[$i+$sum]
     fi
done

echo "sum:$sum"

【腳本39】腳本傳參

使用傳參的方法寫個(gè)腳本夺饲,實(shí)現(xiàn)加減乘除的功能。例如: sh a.sh 1 2施符,這樣會(huì)分別計(jì)算加往声、減、乘戳吝、除的結(jié)果浩销。

要求:

  1. 腳本需判斷提供的兩個(gè)數(shù)字必須為整數(shù)
  2. 當(dāng)做減法或者除法時(shí),需要判斷哪個(gè)數(shù)字大
  3. 減法時(shí)需要用大的數(shù)字減小的數(shù)字
  4. 除法時(shí)需要用大的數(shù)字除以小的數(shù)字听哭,并且結(jié)果需要保留兩個(gè)小數(shù)點(diǎn)慢洋。

參考代碼:

#!/bin/bash

if [ $# -ne 2 ]
then
    echo "The number of parameter is not 2, Please useage: ./$0 1 2"
    exit 1
fi

is_int()
{
    if echo "$1"|grep -q '[^0-9]'
    then
    echo "$1 is not integer number."
    exit 1
    fi
}

max()
{
    if [ $1 -ge $2 ]
    then
    echo $1
    else
    echo $2
    fi
}

min()
{
    if [ $1 -lt $2 ]
    then
    echo $1
    else
    echo $2
    fi
}

sum()
{
    echo "$1 + $2 = $[$1+$2]"
}

minus()
{
    big=`max $1 $2`
    small=`min $1 $2`
    echo "$big - $small = $[$big-$small]"
}

mult()
{
    echo "$1 * $2 = $[$1*$2]"
}

div()
{
    big=`max $1 $2`
    small=`min $1 $2`
    d=`echo "scale =2; $big / $small"|bc`
    echo "$big / $small = $d"
}

is_int $1
is_int $2
sum $1 $2
minus $1 $2
mult $1 $2
div $1 $2

【腳本40】用戶交互腳本

寫一個(gè)腳本,執(zhí)行后陆盘,打印一行提示“Please input a number:”普筹,要求用戶輸入數(shù)值,然后打印出該數(shù)值隘马,然后再次要求用戶輸入數(shù)值太防。直到用戶輸入”end”停止。

代碼參考:

#!/bin/bash

while :
do
 read -p "Please input a number:(end for exit) " n
 num=` echo $n |sed -r 's/[0-9]//g'|wc -c `
 if [ $n == "end" ]
 then
     exit
 elif [ $num -ne 1 ]
 then
     echo "what you input is not a number!Try again!"
 else
     echo "your input number is: $n"
 fi
done

【腳本41】獲取ip

提示用戶輸入網(wǎng)卡的名字酸员,然后我們用腳本輸出網(wǎng)卡的ip蜒车。 看似簡(jiǎn)單讳嘱,但是需要考慮多個(gè)方面,比如我們輸入的不符合網(wǎng)卡名字的規(guī)范醇王,怎么應(yīng)對(duì)呢燥。名字符合規(guī)范,但是根本就沒有這個(gè)網(wǎng)卡有怎么應(yīng)對(duì)寓娩。

代碼參考:

#!/bin/bash
while :
do
     read -p "請(qǐng)輸入網(wǎng)卡名: " e
     e1=`echo "$e" | sed 's/[-0-9]//g'`
     e2=`echo "$e" | sed 's/[a-zA-Z]//g'`
     if [ -z $e ]
     then
        echo "你沒有輸入任何東西"
        continue
     elif [ -z $e1 ]
     then
        echo "不要輸入純數(shù)字在centos中網(wǎng)卡名是以eth開頭后面加數(shù)字"
        continue
     elif [ -z $e2 ]
     then
        echo "不要輸入純字母在centos中網(wǎng)卡名是以eth開頭后面加數(shù)字"
        continue
     else
        break
     fi
done

ip() {
        ifconfig | grep -A1 "$1 " |tail -1 | awk '{print $2}' | awk -F ":" '{print $2}'
}

myip=`ip $e`
if [ -z $myip ]
then
    echo "抱歉,沒有這個(gè)網(wǎng)卡呼渣。"
else
    echo "你的網(wǎng)卡IP地址是$myip"
fi

【腳本42】列出子目錄

腳本的功能:
腳本可以帶參數(shù)也可以不帶棘伴,參數(shù)可以有多個(gè),每個(gè)參數(shù)必須是一個(gè)目錄屁置,腳本檢查參數(shù)個(gè)數(shù)焊夸,若等于0,則列出當(dāng)前目錄本身蓝角;否則阱穗,顯示每個(gè)參數(shù)包含的子目錄。

參考代碼:

#!/bin/bash
if [ $# == 0 ]
then
    ls -ld `pwd`
else
    for i in `seq 1 $#`
    do
        a=$i
        echo "ls ${!a}"
        ls -l ${!a} |grep '^d'
    done
fi

標(biāo)注:

你可能會(huì)對(duì)${!a}有疑問使鹅,這里是一個(gè)特殊用法揪阶,在shell中,$1為第一個(gè)參數(shù)患朱,$2為第二個(gè)參數(shù)鲁僚,以此類推,那么這里的數(shù)字要是一個(gè)變量如何表示呢裁厅?比如n=3,我想取第三個(gè)參數(shù)冰沙,能否寫成 $$n? shell中是不支持的执虹,那怎么辦拓挥? 就用腳本中的這種方法:  a=$n, echo ${!a}

【腳本43】下載文件

創(chuàng)建一個(gè)函數(shù),能接受兩個(gè)參數(shù):

  1. 第一個(gè)參數(shù)為URL袋励,即可下載的文件侥啤;第二個(gè)參數(shù)為目錄,即下載后保存的位置插龄;
  2. 如果用戶給的目錄不存在愿棋,則提示用戶是否創(chuàng)建;如果創(chuàng)建就繼續(xù)執(zhí)行均牢,否則糠雨,函數(shù)返回一個(gè)51的錯(cuò)誤值給調(diào)用腳本;
  3. 如果給的目錄存在徘跪,則下載文件甘邀;下載命令執(zhí)行結(jié)束后測(cè)試文件下載成功與否琅攘;如果成功,則>返回0給調(diào)用腳本松邪,否則坞琴,返回52給調(diào)用腳本;

提示逗抑,在函數(shù)中返回錯(cuò)誤值給調(diào)用腳本剧辐,使用return

參考代碼:

#!/bin/bash

if [ ! -d $2 ]
then
    echo "please make directory"
    exit 51
fi

cd $2
wget $1

n=`echo $?`
if [ $n -eq 0 ];then
    exit 0
else
    exit 52
fi

【腳本44】猜數(shù)字

寫一個(gè)猜數(shù)字腳本,當(dāng)用戶輸入的數(shù)字和預(yù)設(shè)數(shù)字(隨機(jī)生成一個(gè)小于100的數(shù)字)一樣時(shí)邮府,直接退出荧关,否則讓用戶一直輸入,并且提示用戶的數(shù)字比預(yù)設(shè)數(shù)字大或者小褂傀。

參考代碼:

#!/bin/bash
m=`echo $RANDOM`
n1=$[$m%100]
while :
do
    read -p "Please input a number: " n
    if [ $n == $n1 ]
    then
        break
    elif [ $n -gt $n1 ]
    then
        echo "bigger"
        continue
    else
        echo "smaller"
        continue
    fi
done
echo "You are right."

【腳本45】抽簽?zāi)_本

1忍啤、寫一個(gè)腳本執(zhí)行后,輸入名字仙辟,產(chǎn)生隨機(jī)數(shù)01-99之間的數(shù)字同波。
2、如果相同的名字重復(fù)輸入叠国,抓到的數(shù)字還是第一次抓取的結(jié)果未檩,
3、前面已經(jīng)抓到的數(shù)字煎饼,下次不能在出現(xiàn)相同數(shù)字讹挎。
4、第一個(gè)輸入名字后吆玖,屏幕輸出信息筒溃,并將名字和數(shù)字記錄到文件里,程序不能退出
繼續(xù)等待別的學(xué)生輸入沾乘。

參考代碼:

while :
do
    read -p  "Please input a name:" name
    if [ -f /work/test/1.log ];then
    bb=`cat /work/test/1.log | awk -F: '{print $1}' | grep "$name"`

    if [ "$bb" != "$name" ];then  #名字不重復(fù)情況下
        aa=`echo $RANDOM | awk -F "" '{print $2 $3}'`
        while :
        do
          dd=`cat  /work/test/1.log |  awk -F: '{print $2}'  | grep "$aa"`
          if [ "$aa"  ==  "$dd" ];then   #數(shù)字已經(jīng)存在情況下
              echo "數(shù)字已存在."
              aa=`echo $RANDOM | awk -F "" '{print $2 $3}'`
          else
              break
          fi
        done
        echo "$name:$aa" | tee -a /work/test/1.log
     else
     aa=`cat /work/test/1.log |  grep "$name" | awk -F: '{print $2}'` #名字重復(fù)
     echo $aa
     echo "重復(fù)名字."
     fi
  else
      aa=`echo $RANDOM | awk -F "" '{print $2 $3}'`
      echo "$name:$aa" | tee -a  /work/test/1.log
  fi
done

【腳本46】打印只有一個(gè)數(shù)字的行

如題怜奖,把一個(gè)文本文檔中只有一個(gè)數(shù)字的行給打印出來。

參考代碼:

#!/bin/bash

f=/etc/passwd
line=`wc -l $f|awk '{print $1}'`
for l in `seq 1 $line`; do
     n=`sed -n "$l"p $f|grep -o '[0-9]'|wc -l`;
     if [ $n -eq 1 ]; then
        sed -n "$l"p $f
     fi
done

【腳本47】日志歸檔

類似于日志切割翅阵,系統(tǒng)有個(gè)logrotate程序歪玲,可以完成歸檔。但現(xiàn)在我們要自己寫一個(gè)shell腳本實(shí)現(xiàn)歸檔掷匠。

舉例: 假如服務(wù)的輸出日志是1.log滥崩,我要求每天歸檔一個(gè),1.log第二天就變成1.log.1讹语,第三天1.log.2, 第四天 1.log.3 一直到1.log.5

參考答案:

#!/bin/bash

function e_df()
{
    [ -f $1 ] && rm -f $1
}

for i in `seq 5 -1 2`
do
    i2=$[$i-1]
    e_df /data/1.log.$i
    if [ -f /data/1.log.$i2 ]
    then
        mv /data/1.log.$i2 /data/1.log.$i
    fi
done

e_df /data/1.log.1
mv /data/1.log  /data/1.log.1

【腳本48】找出活動(dòng)ip

寫一個(gè)shell腳本钙皮,把192.168.0.0/24網(wǎng)段在線的ip列出來。
思路: for循環(huán), 0.1 — 0.254 依次去ping短条,能通說明在線导匣。

參考代碼:

#!/bin/bash

ips="192.168.1."
for i in `seq 1 254`
do

ping -c 2 $ips$i >/dev/null 2>/dev/null
if [ $? == 0 ]
then
    echo "echo $ips$i is online"
else
    echo "echo $ips$i is not online"
fi
done

【腳本49】檢查錯(cuò)誤

寫一個(gè)shell腳本,檢查指定的shell腳本是否有語法錯(cuò)誤茸时,若有錯(cuò)誤贡定,首先顯示錯(cuò)誤信息,然后提示用戶輸入q或者Q退出腳本可都,輸入其他內(nèi)容則直接用vim打開該shell腳本缓待。

提醒: 檢查shell腳本有沒有語法錯(cuò)誤的命令是 sh -n xxx.sh

參考代碼:

#!/bin/bash
sh -n $1 2>/tmp/err
if [ $? -eq "0" ]
then
    echo "The script is OK."
else
    cat /tmp/err
    read -p "Please inpupt Q/q to exit, or others to edit it by vim. " n
    if [ -z $n ]
    then
        vim $1
        exit
    fi
    if [ $n == "q" -o $n == "Q" ]
    then
        exit
    else
        vim $1
        exit
    fi

fi

【腳本50】格式化輸出

輸入一串隨機(jī)數(shù)字,然后按千分位輸出汹粤。

比如輸入數(shù)字串為“123456789”命斧,輸出為123,456,789

代碼參考:

#!/bin/bash

read -p "輸入一串?dāng)?shù)字:" num
v=`echo $num|sed 's/[0-9]//g'`
if [ -n "$v" ]
then
    echo "請(qǐng)輸入純數(shù)字."
    exit
fi
length=${#num}
len=0
sum=''
for i in $(seq 1 $length)
do
        len=$[$len+1]
        if [[ $len == 3 ]]
        then
                sum=','${num:$[0-$i]:1}$sum
                len=0
        else
                sum=${num:$[0-$i]:1}$sum
        fi
done

if [[ -n $(echo $sum | grep '^,' ) ]]
then
        echo ${sum:1}
else
        echo $sum
fi

上面這個(gè)實(shí)現(xiàn)比較復(fù)雜,下面再來一個(gè)sed的:

#!/bin/bash
read -p "輸入一串?dāng)?shù)字:" num
v=`echo $num|sed 's/[0-9]//g'`
if [ -n "$v" ]
then
    echo "請(qǐng)輸入純數(shù)字."
    exit
fi

echo $num|sed -r '{:number;s/([0-9]+)([0-9]{3})/\1,\2/;t number}'

【腳本51】

1 編寫一個(gè)名為iffile程序嘱兼,它執(zhí)行時(shí)判斷/bin目錄下date文件是否存在?

參考代碼:

!/bin/bash

if [ -f /bin/date ]
then
echo "/bin/date file exist."
else
echo "/bin/date not exist."
fi
2 編寫一個(gè)名為greet的問候程序贤徒,它執(zhí)行時(shí)能根據(jù)系統(tǒng)當(dāng)前的時(shí)間向用戶輸出問候信息芹壕。設(shè)從半夜到中午為早晨,中午到下午六點(diǎn)為下午接奈,下午六點(diǎn)到半夜為晚上踢涌。

參考代碼:

!/bin/bash

h=date +%H
if [ h -ge 0 ] && [h -lt 12 ]
then
echo "Good morning."
elif [ h -ge 12 ] && [h -lt 18 ]
then
echo "Good afternoon."
else
echo "Good evening."
fi
【腳本52】判斷用戶登錄

1 編寫一個(gè)名為ifuser的程序,它執(zhí)行時(shí)帶用戶名作為命令行參數(shù)序宦,判斷該用戶是否已經(jīng)在系統(tǒng)中登錄睁壁,并給出相關(guān)信息。

參考代碼:

!/bin/bash

read -p "Please input the username: " user
if who | grep -qw user then echouser is online.
else
echo $user not online.
fi
2 編寫一個(gè)名為menu的程序互捌,實(shí)現(xiàn)簡(jiǎn)單的彈出式菜單功能潘明,用戶能根據(jù)顯示的菜單項(xiàng)從鍵盤選擇執(zhí)行對(duì)應(yīng)的命令。

參考代碼:

!/bin/bash

function message()
{
echo "0. w"
echo "1. ls"
echo "2.quit"
read -p "Please input parameter: " Par
}
message
while [ Par -ne '2' ] ; do casePar in
0)
w
;;
1)
ls
;;
2)
exit
;;
*)
echo "Unkown command"
;;
esac
message
done
【腳本53】更改后綴名

1 編寫一個(gè)名為chname的程序秕噪,將當(dāng)前目錄下所有的.txt文件更名為.doc文件钳降。

參考代碼:

!/bin/bash

find . -type f -name "*.txt" > /tmp/txt.list
for f in cat /tmp/txt.list
do
n=echo $f|sed -r 's/(.*)\.txt/\1/'
echo "mv fn.doc"
done
2 編寫一個(gè)名為chuser的程序,執(zhí)行中每隔5分鐘檢查指定的用戶是否登錄系統(tǒng)腌巾,用戶名從命令行輸入遂填;如果指定的用戶已經(jīng)登錄,則顯示相關(guān)信息澈蝙。

參考代碼:

!/bin/bash

read -p "Please input the username: " user
while :
do
if who | grep -qw user then echouser login.
else
echo $user not login.
fi
sleep 300
done
【腳本54】判斷pid是否一致

先普及一小段知識(shí),我們用ps aux可以查看到進(jìn)程的PID吓坚,而每個(gè)PID都會(huì)在/proc內(nèi)產(chǎn)生。如果查看到的pid而proc內(nèi)是沒有的灯荧,則是進(jìn)程被人修改了礁击,這就代表你的系統(tǒng)很有可能已經(jīng)被***過了。

請(qǐng)大家用上面知識(shí)編寫一個(gè)shell,定期檢查下自己的系統(tǒng)是否被人***過客税。

參考代碼:

!/bin/bash

ps aux|awk '/[0-9]/ {print 2}'|while read pid do result=`find /proc/ -maxdepth 1 -type d -name "pid"`
if [ -z result ]; then echo "pid abnormal!"
fi
done
【腳本55】一列變?nèi)?/p>

比如1.txt內(nèi)容:

1
2
3
4
5
6
7
處理后應(yīng)該是:

1 2 3
4 5 6
7
可使用sed命令完成:

sed 'N;N;s/\n/ /g' 1.txt
【腳本56】shell的getops

寫一個(gè)getinterface.sh 腳本可以接受選項(xiàng)[i况褪,I],完成下面任務(wù):

使用一下形式:getinterface.sh [-i interface | -I ip]
當(dāng)用戶使用-i選項(xiàng)時(shí)更耻,顯示指定網(wǎng)卡的IP地址测垛;當(dāng)用戶使用-I選項(xiàng)時(shí),顯示其指定ip所屬的網(wǎng)卡秧均。
例:sh getinterface.sh -i eth0
sh getinterface.sh -I 192.168.0.1
當(dāng)用戶使用除[-i | -I]選項(xiàng)時(shí)食侮,顯示[-i interface | -I ip]此信息。
當(dāng)用戶指定信息不符合時(shí)目胡,顯示錯(cuò)誤锯七。(比如指定的eth0沒有,而是eth1時(shí))
參考代碼:

!/bin/bash

ip add |awk -F ":" '1 ~ /^[1-9]/ {print2}'|sed 's/ //g' > /tmp/eths.txt
[ -f /tmp/eth_ip.log ] && rm -f /tmp/eth_ip.log
for eth in cat /tmp/eths.txt
do
ip=ip add |grep -A2 ": $eth" |grep inet |awk '{print $2}' |cut -d '/' -f 1
echo "eth:ip" >> /tmp/eth_ip.log
done
useage()
{
echo "Please useage: 0 -i 網(wǎng)卡名字 or0 -I ip地址"
}

wrong_eth()
{
if ! awk -F ':' '{print 1}' /tmp/eth_ip.log | grep -qw "^1$"
then
echo "請(qǐng)指定正確的網(wǎng)卡名字"
exit
fi
}

wrong_ip()
{
if ! awk -F ':' '{print 2}' /tmp/eth_ip.log | grep -qw "^1$"
then
echo "請(qǐng)指定正確的ip地址"
exit
fi
}

if [ $# -ne 2 ]
then
useage
exit
fi

case 1 in -i) wrong_eth2
grep -w 2 /tmp/eth_ip.log |awk -F ':' '{print2}'
;;

-I)
wrong_ip $2
grep -w $2 /tmp/eth_ip.log |awk -F ':' '{print $1}'
;;

*)
useage
exit

esac
【腳本57】3位隨機(jī)數(shù)字

寫一個(gè)腳本產(chǎn)生隨機(jī)3位的數(shù)字誉己,并且可以根據(jù)用戶的輸入?yún)?shù)來判斷輸出幾組眉尸。 比如,腳本名字為 number3.sh巨双。
執(zhí)行方法:
bash number3.sh
直接產(chǎn)生一組3位數(shù)字噪猾。
bash number3.sh 10
插上10組3位數(shù)字。

思路: 可以使用echo $RANDOM獲取一個(gè)隨機(jī)數(shù)字筑累,然后再除以10袱蜡,取余獲取0-9隨機(jī)數(shù)字,三次運(yùn)算獲得一組慢宗。

參考代碼:

!/bin/bash

get_a_num() {
n=[RANDOM%10]
echo $n
}

get_numbers() {
for i in 1 2 3; do
a[i]=`get_a_num` done echo{a[@]}
}

if [ -n "1" ]; then m=`echo1|sed 's/[0-9]//g'if [ -n "$m" ]; then echo "Useage bash $0 n, n is a number, example: bash $0 5" exit else for i inseq 1 $1`
do
get_numbers
done
fi
else
get_numbers

fi
【腳本58】檢查服務(wù)

先判斷是否安裝http和mysql坪蚁,沒有安裝進(jìn)行安裝,安裝了檢查是否啟動(dòng)服務(wù)镜沽,若沒有啟動(dòng)則需要啟動(dòng)服務(wù)敏晤。

說明:操作系統(tǒng)為centos6,httpd和mysql全部為rpm包安裝淘邻。

參考代碼:

!/bin/bash

if_install()
{
n=rpm -qa|grep -cw "$1"
if [ n -eq 0 ] then echo "1 not install."
yum install -y 1 else echo "1 installed."
fi
}

if_install httpd
if_install mysql-server

chk_ser()
{
p_n=ps -C "$1" --no-heading |wc -l
if [ p_n -eq 0 ] then echo "1 not start."
/etc/init.d/1 start else echo "1 started."
fi
}

chk_httpd
chk_mysqld
【腳本59】判斷日期是否合法

用shell腳本判斷輸入的日期是否合法茵典。就是判斷日期是都是真實(shí)的日期,比如20170110就是合法日期宾舅,20171332就不合法

參考代碼:

!/bin/bash

check date

if [ # -ne 1 ] || [{#1} -ne 8 ]
then
echo "Usage: bash $0 yyyymmdd"
exit 1
fi

datem=1 year={datem:0:4}
month={datem:4:2} day={datem:6:2}

if echo day|grep -q '^0' then day=`echoday |sed 's/^0//'`
fi

if cal monthyear >/dev/null 2>/dev/null
then
daym=cal $month $year|egrep -v "$year|Su"|grep -w "$day"
if [ "$daym" != "" ]
then
echo ok
else
echo "Error: Please input a wright date."
exit 1
fi
else
echo "Error: Please input a wright date."
exit 1
fi
【腳本60】監(jiān)控網(wǎng)卡

1.每10分鐘檢測(cè)一次指定網(wǎng)卡的流量
2.如果流量為0统阿,則重啟網(wǎng)卡

參考代碼:

!/bin/bash

LANG=en
n1=sar -n DEV 1 60 |grep eth0 |grep -i average|awk '{print $5}'|sed 's/\.//g'
n2=sar -n DEV 1 60 |grep eth0 |grep -i average|awk '{print $6}'|sed 's/\.//g'
if [ n1 == "000" ] && [n2 == "000" ]
then
ifdown eth0
ifup eth0
fi
然后寫個(gè)cron,10分鐘執(zhí)行一次

【腳本61】監(jiān)控web可用性

寫一個(gè)shell腳本筹我,通過curl -I 返回的狀態(tài)碼來判定所訪問的網(wǎng)站是否正常扶平。比如,當(dāng)狀態(tài)碼為200時(shí)蔬蕊,才算正常结澄。

參考代碼:

/bin/bash

url="http://www.apelearn.com/index.php"
sta=curl -I $url 2>/dev/null |head -1 |awk '{print $2}'

if [ sta != "200" ] then python /usr/local/sbin/mail.py xxx@qq.com "url down." "$url down"
fi
【腳本62】文件打包

需求:將用戶家目錄(考慮到執(zhí)行腳本的用戶可能是普通用戶也可能是root)下面小于5KB的文件打包成tar.gz的壓縮包,并以當(dāng)前日期為文件名前綴,例如今天打包的文件為2017-09-15.tar.gz麻献。

參考代碼:

!/bin/bash

t=date +%F
cd HOME tar czft.tar.gz find . -type f -size -5k
【腳本63】端口解封

一個(gè)小伙伴提到一個(gè)問題们妥,他不小心用iptables規(guī)則把sshd端口22給封掉了,結(jié)果不能遠(yuǎn)程登陸勉吻,要想解決這問題监婶,還要去機(jī)房,登陸真機(jī)去刪除這規(guī)則齿桃。 問題來了惑惶,要寫個(gè)監(jiān)控腳本,監(jiān)控iptables規(guī)則是否封掉了22端口短纵,如果封掉了带污,給打開。 寫好腳本香到,放到任務(wù)計(jì)劃里鱼冀,每分鐘執(zhí)行一次。

參考代碼:

!/bin/bash

check sshd port drop

/sbin/iptables -nvL --line-number|grep "dpt:22"|awk -F ' ' '{print 4}' > /tmp/drop.txt i=`cat /tmp/drop.txt|head -n 1|egrep -iE "DROP|REJECT"|wc -l` if [i -gt 0 ]
then
/sbin/iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT
fi
【腳本64】統(tǒng)計(jì)分析日志

已知nginx訪問的日志文件在/usr/local/nginx/logs/access.log內(nèi)

請(qǐng)統(tǒng)計(jì)下早上10點(diǎn)到12點(diǎn) 來訪ip最多的是哪個(gè)?

日志樣例:

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” “0.516”

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” “0.065”
實(shí)現(xiàn)這個(gè)需求使用如下命令即可:

grep '15/Sep/2017:1[0-2]:[0-5][0-9]:' /usr/local/nginx/logs/access.log|awk '{print $1}'|sort -n|uniq -c |sort -n|tail -n1
【腳本65】打印數(shù)字

寫一個(gè)shell腳本悠就。提示你輸入一個(gè)暫停的數(shù)字闰集,然后從1打印到該數(shù)字腐螟。然后詢問是否繼續(xù)回官。繼續(xù)的話在輸入個(gè)在數(shù)字 接著打印喷兼。不繼續(xù)退出虱疏。

例:如果輸入的是5踢京,打印1 2 3 4 5 然后繼續(xù) 輸入15 然后打印 6 7 …14 15 依此類推翔试。

參考代碼:

!/bin/bash

read -p "請(qǐng)輸入您想要暫停的數(shù)字:" number_1

for i in seq 1 $number_1;
do
echo $i
done

read -p "是否繼續(xù)輸入數(shù)字爆土?" a
if [ a == "yes" ];then read -p "請(qǐng)繼續(xù)輸入您想要暫停的數(shù)字:" number_2 number_3=[number_1+1] if [number_2 -gt number_1 ];then for h in `seqnumber_3 number_2`; do echoh
done
else
echo "輸入數(shù)字錯(cuò)誤鹉究,請(qǐng)輸入大于的數(shù)字!"
fi
else
exit
fi
【腳本66】給文檔增加內(nèi)容

在文本文檔1.txt第5行(假設(shè)文件行數(shù)大于5)后面增加如下內(nèi)容:

This is a test file.

Test insert line into this file.

參考命令:

sed -i "5a # This is a test file.\n# Test insert line into this file." 1.txt
【腳本67】備份etc下面文件

設(shè)計(jì)一個(gè)shell程序宇立,在每月第一天備份并壓縮/etc目錄的所有內(nèi)容,存放在/root/bak目錄里自赔,且文件名為如下形式”yymmdd_etc.tar.gz”妈嘹,yy為年,mm為月绍妨,dd為日润脸。

參考代碼:

!/bin/sh

if [ ! -d /root/bak ]
then
mkdir /root/bak
fi
prefix=date +%y%m%d
d=date +%d
if [ d == "01" ] then cd /etc/ tar czf /root/bak/prefix_etc.tar.gz ./
fi
【腳本68】計(jì)算單詞重復(fù)次數(shù)

將文件內(nèi)所有的單詞的重復(fù)次數(shù)計(jì)算出來,只需要列出重復(fù)次數(shù)最多的10個(gè)單詞他去。

假設(shè)文檔名字叫做a.txt毙驯,使用如下命令即可:

sed 's/[^a-zA-Z]/ /g' a.txt|xargs -n1 |sort |uniq -c |sort -nr |head
【腳本69】成員分組

需求是,把所有的成員平均得分成若干個(gè)小組灾测。這里爆价,我會(huì)提供一個(gè)人員列表,比如成員有50人,需要分成7個(gè)小組铭段,要求隨機(jī)性骤宣,每次和每次分組的結(jié)構(gòu)應(yīng)該不一致。

假設(shè)成員列表文件為members.txt

參考代碼:

!/bin/bash

f=members.txt
n=wc -l $f|awk '{print $1}'
get_n()

{
l=echo $1|wc -c
n1=RANDOM n2=[n1+l]
g_id=[n1%7]
if [ g_id -eq 0 ] then g_id=7 fi echog_id
}

for i in seq 1 7
do
[ -f n_i.txt ] && rm -f n_i.txt
done
for i in seq 1 $n
do
name=sed -n "$i"p $f
g=get_n $name
echo name >> n_g.txt
done

nu(){
wc -l 1|awk '{print1}'
}

max(){
ma=0
for i in seq 1 7
do
n=nu n_$i.txt
if [ n -gtma ]
then
ma=n fi done echoma
}

min(){
mi=50
for i in seq 1 7
do
n=nu n_$i.txt
if [ n -ltmi ]
then
mi=n fi done echomi
}

ini_min=1
while [ ini_min -le 7 ] do m1=`max` m2=`min` ini_min=m2 for i in `seq 1 7` do n=`nu n_i.txtif [ $n -eq $m1 ] then f1=n_$i.txt elif [ $n -eq $m2 ] then f2=n_$i.txt fi done name=tail -n1 f1` echoname >> f2 sed -i "/name/d" f1 ini_min=[$ini_min+1]
done

for i in seq 1 7
do
echo "i 組成員有:" cat n_i.txt
echo
done
【腳本70】shell中的小數(shù)

有一組式子如下:

a=0.5
b=3
c=a*b
求c的值序愚,參考代碼:

!/bin/bash

a=0.5
b=3
c=echo "scale=1;$a*$b"|bc
echo $c
【腳本71】a.txt有b.txt沒有

有兩個(gè)文件a.txt和b.txt憔披,需求是,把a(bǔ).txt中有的并且b.txt中沒有的行找出來展运,并寫入到c.txt活逆,然后計(jì)算c.txt文件的行數(shù)。

參考代碼:

!/bin/bash

n=wc -l a.txt|awk '{print $1}'
[ -f c.txt ] && rm -f c.txt
for i in seq 1 $n
do
l=sed -n "$i"p a.txt
if ! grep -q "^l" b.txt
then
echo $l >>c.txt
fi
done
wc -l c.txt

或者用grep實(shí)現(xiàn)
grep -vwf b.txt a.txt > c.txt拗胜; wc -l c.txt
【腳本72】殺死進(jìn)程

把當(dāng)前用戶下所有進(jìn)程名字中含有”java”的進(jìn)程關(guān)閉蔗候。

參考答案:

ps -u USER |awk 'NF ~ /java/ {print $1}'|xargs kill
【腳本73】備份數(shù)據(jù)表

用shell實(shí)現(xiàn),以并發(fā)進(jìn)程的形式將mysql數(shù)據(jù)庫所有的表備份到當(dāng)前目錄埂软,并把所有的表壓縮到一個(gè)壓縮包文件里锈遥。

假設(shè)數(shù)據(jù)庫名字為mydb,用戶名為zero勘畔,密碼為passwd所灸。

提示: 在shell中加上&可以將命令丟到后臺(tái),從而可以同時(shí)執(zhí)行多條命令達(dá)到并發(fā)的效果炫七。

參考代碼:

!/bin/bash

pre=date +%F
for d in mysql -uaming -ppasswd mydb -e "show tables"|grep -v 'Tables_in_'
do
mysqldump -uaming -ppasswd mydb d >d.sql &
done
tar czf $pre.tar.gz *.sql
rm -f *.sql
【腳本74】監(jiān)控節(jié)點(diǎn)

一個(gè)網(wǎng)站爬立,使用了cdn,全國(guó)各地有幾十個(gè)節(jié)點(diǎn)万哪。需要你寫一個(gè)shell腳本來監(jiān)控各個(gè)節(jié)點(diǎn)是否正常侠驯。

假如:

監(jiān)控的url為www.xxx.com/index.php
源站ip為88.88.88.88
參考代碼:

!/bin/bash

url="www.xxx.com/index.php"
s_ip="88.88.88.88"
curl -x s_ip:80url > /tmp/source.html 2>/dev/null

for ip in cat /tmp/ip.txt
do
curl -x ip:80url 2>/dev/null >/tmp/ip.html [ -f /tmp/ip.diff ] && rm -f /tmp/ip.diff touch /tmp/ip.diff
diff /tmp/source.html /tmp/ip.html > /tmp/ip.diff 2>/dev/null
n=wc -l /tmp/$ip.diff|awk '{print $1}'
if [ n -lt 0 ] then echo "nodeip sth wrong."
fi
done
【腳本75】破解字符串

已知下面的字符串是通過RANDOM隨機(jī)數(shù)變量md5sum|cut-c 1-8截取后的結(jié)果,請(qǐng)破解這些字符串對(duì)應(yīng)的md5sum前的RANDOM對(duì)應(yīng)數(shù)字奕巍?

21029299
00205d1c
a3da1677
1f6d12dd
890684ba
解題思路:通過每次傳遞一個(gè)參數(shù)的方式吟策,來實(shí)現(xiàn)依次破解,$RANDOM的范圍為0-32767的止。

參考代碼:

!/bin/bash

for n in {0..32767}
do
MD5=echo $n | md5sum | cut -c 1-8
if [ "MD5" == "1" ];then
echo "n1 "
break
fi
done
【腳本76】判斷cpu廠商

寫一個(gè)腳本:

判斷當(dāng)前主機(jī)的CPU生產(chǎn)商檩坚,其信息在/proc/cpuinfo文件中vendor id一行中。
如果其生產(chǎn)商為AuthenticAMD诅福,就顯示其為AMD公司匾委;
如果其生產(chǎn)商為GenuineIntel,就顯示其為Intel公司权谁;
否則剩檀,就說其為非主流公司。
參考代碼:

!/bin/bash

m=cat /proc/cpuinfo |grep vendor_id|awk -F":" '{print $2}'|tail -1
if [ m == "GenuineIntel" ] then echo "cpu is 英特爾" elif [m == "AuthenticAMD" ]
then
echo "cpu is AMD"
else
echo "cpu is 非主流"
fi
【腳本77】監(jiān)控cpu使用率

用shell寫一個(gè)監(jiān)控服務(wù)器cpu使用率的監(jiān)控腳本旺芽。

思路:用top -bn1 命令沪猴,取當(dāng)前空閑cpu百份比值(只取整數(shù)部分)辐啄,然后用100去劍這個(gè)數(shù)值。

參考代碼:

!/bin/bash

while :
do
idle=top -bn1 |sed -n '3p' |awk '{print $5}'|cut -d . -f1
use=[100-idle]
if [ $use -gt 90 ]
then
echo "cpu use percent too high."
#發(fā)郵件省略
fi
sleep 10
done
【腳本78】獲取子進(jìn)程

說明:本shell題目是一個(gè)網(wǎng)友在公眾號(hào)中提問的运嗜,正好利用這個(gè)每日習(xí)題的機(jī)會(huì)拿出來讓大家一起做一做壶辜。

給出一個(gè)進(jìn)程PID,打印出該進(jìn)程下面的子進(jìn)程以及子進(jìn)程下面的所有子進(jìn)程担租。(只需要考慮子進(jìn)程的子進(jìn)程砸民,再往深層次則不考慮)

參考代碼:

!/bin/bash

read -p "please input a pid number: " p
ps -elf > /tmp/ps.log

is_ppid(){
awk '{print 5}' /tmp/ps.log > /tmp/ps1.log if ! grep -qw "1" /tmp/ps1.log
then
echo "PID $1 不是系統(tǒng)進(jìn)程號(hào),或者它不是父進(jìn)程"
return 1
fi
}

is_ppid $p

if [ $? -eq "1" ]
then
exit
fi

print_cpid(){
p=1 awk -v p1=p '5 == p1 {print4}' /tmp/ps.log |sort -n |uniq >/tmp/p1.log
n=wc -l /tmp/p1.log|awk '{print $1}'
if [ n -ne 0 ] then echo "PIDp 子進(jìn)程 pid 如下:"
cat /tmp/p1.log
else
echo "PID $p 沒有子進(jìn)程"
fi
}

print_cpid $p

for cp in cat /tmp/p1.log
do
print_cpid $cp
done
另外奋救,一條命令查詢的方法是:

pstree -p pid
【腳本79】自動(dòng)添加項(xiàng)目

需求背景:
服務(wù)器上岭参,跑的lamp環(huán)境,上面有很多客戶的項(xiàng)目尝艘,每個(gè)項(xiàng)目就是一個(gè)網(wǎng)站演侯。 由于客戶在不斷增加,每次增加一個(gè)客戶背亥,就需要配置相應(yīng)的mysql秒际、ftp以及httpd. 這種工作是重復(fù)性非常強(qiáng)的,所以用腳本實(shí)現(xiàn)非常合適狡汉。

mysql增加的是對(duì)應(yīng)客戶項(xiàng)目的數(shù)據(jù)庫娄徊、用戶、密碼盾戴,ftp增加的是對(duì)應(yīng)項(xiàng)目的用戶寄锐、密碼(使用vsftpd,虛擬用戶模式)尖啡,httpd就是要增加虛擬主機(jī)配置段锐峭。

參考代碼:

!/bin/bash

webdir=/home/wwwroot
ftpudir=/etc/vsftpd/vuuser
mysqlc="/usr/bin/mysql -uroot -xxxxxx"
httpd_config_f="/usr/local/apache2/conf/extra/httpd-vhosts.conf"

add_mysql_user()
{
mysql_p=mkpasswd -s 0 -l 12
echo "promysql_p" >/tmp/pro.txtmysqlc <<EOF
grant all on p.* to "pro"@'127.0.0.1' identified by "$mysql_p";
EOF
}

add_ftp_user()

{
ftp_p=mkpasswd -s 0 -l 12
echo "pro" >> /root/login.txt echo "ftp_p" >> /root/login.txt
db_load -T -t hash -f /root/login.txt /etc/vsftpd/vsftpd_login.db
cd ftpudir cp aaapro //這里的aaa是一個(gè)文件,是之前的一個(gè)項(xiàng)目可婶,可以作為配置模板
sed -i "s/aaa/pro/"pro //把里面的aaa改為新的項(xiàng)目名字
/etc/init.d/vsftpd restart
}

config_httpd()

{
mkdir webdir/pro
chown vsftpd:vsftpd webdir/pro
echo -e "<VirtualHost *:80> \n DocumentRoot "/home/internet/www/pro/" \n ServerNamedom \n #ServerAlias \n</VirtualHost> " >> $httpd_config_f
/usr/local/apache2/bin/apachectl graceful
}

read -p "input the project name: " pro
read -p "input the domain: " dom

add_mysql_user
add_ftp_user
config_httpd
【腳本80】計(jì)算器

用shell寫一個(gè)簡(jiǎn)易計(jì)算器,可以實(shí)現(xiàn)加援雇、減矛渴、乘、除運(yùn)算惫搏,假如腳本名字為1.sh具温,執(zhí)行示例:./1.sh 1 + 2

參考代碼:

!/bin/bash

if [ # -ne 3 ] then echo "參數(shù)個(gè)數(shù)不為3" echo "當(dāng)使用乘法時(shí),需要加上脫義符號(hào)筐赔,例如0 1 * 2"
exit 1;
fi

num1=echo $1|sed 's/[0-9.]//g' ;
if [ -n "num1" ] then echo "1 不是數(shù)字" ;
exit 1
fi

num3=echo $3|sed 's/[0-9.]//g' ;
if [ -n "num3" ] then echo "3 不是數(shù)字" ;
exit 1
fi

case 2 in +) echo "scale=2;1+$3" | bc
;;

-)
echo "scale=2;1-3" | bc
;;

*)
echo "scale=2;1*3" | bc
;;

/)
echo "scale=2;1/3" | bc
;;

*)
echo "$2 不是運(yùn)算符"
;;
esac
【腳本81】判斷沒有文件

判斷所給目錄內(nèi)哪些二級(jí)目錄下沒有text.txt文件铣猩。

有text.txt文件的二級(jí)目錄,根據(jù)文件計(jì)算選項(xiàng)中單詞數(shù)最大的值(選項(xiàng)間以|分割茴丰,單詞間以空格分隔)达皿。

假如腳本名字為1.sh天吓, 運(yùn)行腳本的格式為 ./1.sh 123 root,其中123為目錄名字峦椰,而root為要計(jì)算數(shù)量的單詞龄寞。

說明: 這個(gè)shell腳本題目出的有點(diǎn)歧義。 原題給的描述不是很清楚汤功,我另外又改了一下需求物邑,依然不是很清晰。在這里我再做一個(gè)補(bǔ)充: 對(duì)于有test.txt的目錄滔金,計(jì)算出該test.txt文件里面所給出單詞的次數(shù)色解。不用找最大。

參考代碼:

!/bin/bash

if [ # -ne 2 ] then echo "useage0 dir word"
exit 1
fi

if [ -d 1 ] then cd1
else
echo "$1目錄不存在"
exit 1
fi

for f in ls $1
do
if [ -d f ] then if [ -ff/test.txt ]
then
n=grep -cw "$2" $f/test.txt
echo "1/f/test.txt 里面有n個(gè)2"
else
echo "1/f 下面沒有test.txt"
fi
fi
done
【腳本82】打印正方形

交互式腳本餐茵,根據(jù)提示科阎,需要用戶輸入一個(gè)數(shù)字作為參數(shù),最終打印出一個(gè)正方形钟病。

在這里我提供一個(gè)linux下面的特殊字符■萧恕,可以直接打印出來。

示例: 如果用戶輸入數(shù)字為5肠阱,則最終顯示的效果為:

■ ■ ■ ■ ■

■ ■ ■ ■ ■

■ ■ ■ ■ ■

■ ■ ■ ■ ■

■ ■ ■ ■ ■
參考代碼:

!/bin/bash

read -p "please input a number:" sum
a=echo $sum |sed 's/[0-9]//g'
if [ -n "$a" ]
then
echo "請(qǐng)輸入一個(gè)純數(shù)字票唆。"
exit 1
fi

for n in seq $sum
do
for m in seq $sum
do
if [ m -ltsum ]
then
echo -n "■ "
else
echo "■"
fi
done
done
【腳本83】問候用戶

寫一個(gè)腳本,依次向/etc/passwd中的每個(gè)用戶問好屹徘,并且說出對(duì)方的ID是什么:

Hello,root走趋,your UID is 0.
參考命令:

awk -F ':' '{print "Hello,"1",your uid is "3.}' /etc/passwd
【腳本84】按要求處理文本

linux系統(tǒng) /home目錄下有一個(gè)文件test.xml,內(nèi)容如下:

<configuration>
<artifactItems>
<artifactItem>
<groupId>zzz</groupId>
<artifactId>aaa</artifactId>
</artifactItem>
<artifactItem>
<groupId>xxx</groupId>
<artifactId>yyy</artifactId>
</artifactItem>

</artifactItems>
</configuration>
請(qǐng)寫出shell腳本刪除文件中的注釋部分內(nèi)容噪伊,獲取文件中所有artifactItem的內(nèi)容簿煌,并用如下格式逐行輸出 artifactItem:groupId:artifactId

分析:這個(gè)文件比較特殊,但是卻很有規(guī)律鉴吹。注釋部分內(nèi)容其實(shí)就是<!– –>中間的內(nèi)容姨伟,所以我們想辦法把這些內(nèi)容刪除掉就ok了。而artifactItem的內(nèi)容豆励,其實(shí)就是獲取<artifactItem></artifactItem>中間的內(nèi)容夺荒。然后想辦法用提到的格式輸出即可。

參考代碼:

!/bin/bash

egrep -v '' 1.txt |tee 2.txt //這行就是刪除掉注釋的行
grep -n 'artifactItem>' 2.txt |awk '{print 1}' |sed 's/://' > /tmp/line_number.txt n=`wc -l /tmp/line_number.txt|awk '{print1}'`

get_value(){
sed -n "1,2"p 2.txt|awk -F '<' '{print 2}'|awk -F '>' '{print1,2}' > /tmp/value.txt nu=`wc -l /tmp/value.txt|awk '{print1}'for i inseq 1 nu` do x=`sed -n "i"p /tmp/value.txt|awk '{print 1}'` y=`sed -n "i"p /tmp/value.txt|awk '{print 2}'` echo artifactItem:x:$y
done
}

n2=[n/2]

for j in seq 1 $n2
do
m1=[j2-1]
m2=[j
2]
nu1=sed -n "$m1"p /tmp/line_number.txt
nu2=sed -n "$m2"p /tmp/line_number.txt
nu3=[nu1+1]
nu4=[nu2-1]
get_value nu3nu4
done
【腳本85】判斷函數(shù)

請(qǐng)使用條件函數(shù)if撰寫一個(gè)shell函數(shù) 函數(shù)名為 f_judge良蒸,實(shí)現(xiàn)以下功能:

當(dāng)/home/log 目錄存在時(shí) 將/home目錄下所有tmp開頭的文件或目錄移/home/log 目錄技扼。
當(dāng)/home/log目錄不存在時(shí),創(chuàng)建該目錄嫩痰,然后退出剿吻。
參考代碼:

!/bin/bash

f_judge (){
if [ -d /home/log ]
then
mv /home/tmp* /home/log/
else
mkdir -p /home/log
exit
fi
}
【腳本86】批量殺進(jìn)程

linux系統(tǒng)中,根目錄/root/下有一個(gè)文件ip-pwd.ini串纺,內(nèi)容如下:

10.111.11.1,root,xyxyxy

10.111.11.1,root,xzxzxz

10.111.11.1,root,123456

10.111.11.1,root,xxxxxx

……
文件中每一行的格式都為linux服務(wù)器的ip,root用戶名,root密碼丽旅,請(qǐng)用一個(gè)shell批量將這些服務(wù)器中的所有tomcat進(jìn)程kill掉椰棘。

講解: 有了ip,用戶名和密碼魔招,剩下的就是登錄機(jī)器晰搀,然后執(zhí)行命令了。批量登錄機(jī)器办斑,并執(zhí)行命令外恕,咱們課程當(dāng)中有講過一個(gè)expect腳本。所以本題就是需要這個(gè)東西來完成乡翅。

首先編輯expect腳本 kill_tomcat.expect:

!/usr/bin/expect

set passwd [lindex argv 0] set host [lindexargv 1]
spawn ssh root@$host

expect {
"yes/no" { send "yes\r"; exp_continue}
"password:" { send "$passwd\r" }
}

expect "]"
send "killall java\r"
expect "]
"
send "exit\r"
編輯完后需要給這個(gè)文件執(zhí)行權(quán)限:

chmod a+x kill_tomcat.expect
然后編輯shell腳本:

!/bin/bash

n=wc -l ip-pwd.ini
for i in seq 1 $n
do
ip=sed -n "$n"p ip-pwd.ini |awk -F ',' '{print $1}'
pw=sed -n "$n"p ip-pwd.ini |awk -F ',' '{print $3}'
./kill_tomcat.expect pwip
done
【腳本87】處理日志

寫一個(gè)腳本查找/data/log目錄下鳞疲,最后創(chuàng)建時(shí)間是3天前,后綴是*.log的文件蠕蚜,打包后發(fā)送至192.168.1.2服務(wù)上的/data/log下尚洽,并刪除原始.log文件,僅保留打包后的文件

參考代碼:

!/bin/bash

find /data/log -name “*.log” -mtime +3 > /tmp/file.list
cd /data/log
tar czvf log.tar.gz cat /tmp/file.list|xargs
rsync -a log.tar.gz 192.168.1.2:/data/log # 這一步需要提前做一個(gè)免密碼登錄
for f in cat /tmp/file.list
do
rm -f $f
done
【腳本88】處理文本

有如下文本靶累,其中前5行內(nèi)容為

1111111:13443253456
2222222:13211222122
1111111:13643543544
3333333:12341243123
2222222:12123123123
用shell腳本處理后腺毫,按下面格式輸出:

[1111111]
13443253456
13643543544
[2222222]
13211222122
12123123123
[3333333]
12341243123
參考代碼:

! /bin/bash

sort -n filename |awk -F ':' '{print $1}'|uniq >id.txt

for id in cat id.txt; do
echo "[id]" awk -v id2=id -F ':' '1==id2 {print2}' filename
#另外的方式為: awk -F ':' '1=="'id'" {print $2}' filename
done
【腳本89】清理日志

要求:兩類機(jī)器一共300多臺(tái),寫個(gè)腳本自動(dòng)清理這兩類機(jī)器里面的日志文件挣柬。在堡壘機(jī)批量發(fā)布潮酒,也要批量發(fā)布到crontab里面。

A類機(jī)器日志存放路徑很統(tǒng)一邪蛔,B類機(jī)器日志存放路徑需要用匹配(因?yàn)檫@個(gè)目錄里除了日志外急黎,還有其他文件,不能刪除侧到。匹配的時(shí)候可用.log)

A類:/opt/cloud/log/ 刪除7天前的
B類: /opt/cloud/instances/ 刪除15天前的

要求寫在一個(gè)腳本里面勃教。不用考慮堡壘機(jī)上的操作,只需要寫出shell腳本匠抗。

參考代碼:

!/bin/bash

dir1=/opt/cloud/instances/
dir2=/opt/cloud/log/

if [ -d dir1 ];then finddir1 -type f -name "*.log" -mtime +15 |xargs rm -f
elif [ -d dir2 ];then finddir2 -type f -mtime +7 |xargs rm -f
fi
【腳本90】

貸款有兩種還款的方式:等額本金法和等額本息法

簡(jiǎn)單說明一下等額本息法與等額本金法的主要區(qū)別:

等額本息法的特點(diǎn)是:每月的還款額相同故源,在月供中“本金與利息”的分配比例中,前半段時(shí)期所還的利息比例大汞贸、本金比例小心软,還款期限過半后逐步轉(zhuǎn)為本金比例大、利息比例小著蛙。所支出的總利息比等額本金法多,而且貸款期限越長(zhǎng)耳贬,利息相差越大踏堡。

等額本金法的特點(diǎn)是:每月的還款額不同,它是將貸款額按還款的總月數(shù)均分(等額本金)咒劲,再加上上期剩余本金的月利息顷蟆,形成一個(gè)月還款額诫隅,所以等額本金法第一個(gè)月的還款額最多 ,爾后逐月減少帐偎,越還越少逐纬。所支出的總利息比等額本息法少。

兩種還款方式的比較不是我們今天的討論范圍削樊,我們的任務(wù)就是做一個(gè)貸款計(jì)算器豁生。

其中:等額本息每月還款額的計(jì)算公式是:
[貸款本金×月利率×(1+月利率)還款月數(shù)]÷[(1+月利率)還款月數(shù)-1]

參考代碼:

!/bin/bash

read -p "請(qǐng)輸入貸款總額(單位:萬元):" dkzewy
read -p "請(qǐng)輸入貸款年利率(如年利率為6.5%,直接輸入6.5):" dknll
read -p "請(qǐng)輸入貸款年限(單位:年):" dknx
echo "貸款計(jì)算方式:"
echo "1)等額本金計(jì)算法"
echo "2)等額本息計(jì)算法"
read -p "請(qǐng)選擇貸款方式(1|2)" dkfs
dkze=echo "scale=2;$dkzewy*10000 " | bc -l
dkll=echo "scale=6;$dknll/100 " | bc -l
dkyll=echo "scale=6;$dkll/12 " | bc -l
dkqc=[dknx*12]
echo "期次 本月還款額 本月利息 未還款額"

debjjsf()
{
yhbj=echo "scale=2;($dkze/$dkqc)/1 " | bc -l
whbj=dkze for((i=1;i<=dkqc;i++))
do
bylx=echo "scale=2;($whbj*$dkyll)/1 " | bc -l
bybx=echo "scale=2;($yhbj+$bylx)/1 " | bc -l
yhke=echo "scale=2;($yhbj*$i)/1 " | bc -l
whbj=echo "$dkze-$yhke " | bc -l
if [ i -eqdkqc ]
then
yhbj=echo "scale=2;($yhbj+$whbj)/1 " | bc -l
whbj="0.00"
bybx=echo "scale=2;($yhbj+$bylx)/1 " | bc -l
fi
echo "ibybx bylxwhbj"
done
}

debxjsf()
{
bybx=echo "scale=2;(($dkze*$dkyll*((1+$dkyll)^$dkqc))/(((1+$dkyll)^$dkqc)-1))/1 " | bc -l
whbj=dkze for((i=1;i<=dkqc;i++))
do
bylx=echo "scale=2;($whbj*$dkyll)/1 " | bc -l
yhbj=echo "scale=2;($bybx-$bylx)/1 " | bc -l
whbj=echo "scale=2;($whbj-$yhbj)/1 " | bc -l
if [ i -eqdkqc ]
then
bybx=echo "scale=2;($yhbj+$whbj)/1 " | bc -l
whbj="0.00"
fi
echo "ibybx bylxwhbj"
done
}

case $dkfs in
1) debjjsf
;;
2) debxjsf
;;
*) exit 1
;;
esac
【腳本91】監(jiān)控磁盤io

阿里云的機(jī)器漫贞,今天收到客服來的電話甸箱,說服務(wù)器的磁盤io很重。于是登錄到服務(wù)器查看迅脐,并沒有發(fā)現(xiàn)問題芍殖,所以懷疑是間歇性地。

正要考慮寫個(gè)腳本的時(shí)候谴蔑,幸運(yùn)的抓到了一個(gè)線索豌骏,造成磁盤io很高的幕后黑手是mysql。此時(shí)去show processlist隐锭,但未發(fā)現(xiàn)隊(duì)列窃躲。原來只是一瞬間。

只好繼續(xù)來寫腳本成榜,思路是框舔,每5s檢測(cè)一次磁盤io,當(dāng)發(fā)現(xiàn)問題去查詢mysql的processlist赎婚。

提示:你可以用iostat -x 1 5 來判定磁盤的io刘绣,主要看%util

參考代碼:

!/bin/bash

while :
do
n=iostat -x 1 5 |tail -n3|head -n1 |awk '{print $NF}'|cut -d. -f1
if [ n -gt 70 ] then echo "`date` util% isn%" >>/tmp/mysql_processlist.log
mysql -uroot -pxxxxxx -e "show full processlist" >> /tmp/mysql_processlist.log
fi
sleep 5
done
【腳本92】截取tomcat日志

寫一個(gè)截取tomcat catalina.out日志的腳本。

tomcat實(shí)例t1-t4:

[root@server ~]# tree -L 1 /opt/TOM/
/opt/TOM/
├── crontabs
├── t1
├── t2
├── t3
└── t4

5 directories, 0 files
catalina.out日志路徑:

[root@server ~]# 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
要求:

這個(gè)腳本可以取tomcat實(shí)例t1-t4的日志
這個(gè)腳本可以自定義取日志的起始點(diǎn)挣输,比如取今天早上10點(diǎn)之后到現(xiàn)在的數(shù)據(jù)
這個(gè)腳本可以自定義取日志的起始點(diǎn)和終點(diǎn)纬凤,比如取今天早上9點(diǎn)到晚上8點(diǎn)的數(shù)據(jù)
catalina.out 日志片段:

Mar 29, 2016 1:52:24 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler [“http-bio-8080”]
Mar 29, 2016 1:52:24 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler [“ajp-bio-8009”]
Mar 29, 2016 1:52:24 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 2102 ms
參考代碼:

!/bin/bash

export LANG=en_US.UTF-8
export PATH=PATH IPADD=`/sbin/ifconfig | grep "inet addr" | head -1 | awk '{print2}'| awk -F '.' '{print NF}'` LOGFILE="/opt/TOM/1/logs/catalina.out"
YEAR=date +%Y
DATE=date +%m%d_%H%M
TOMCAT=1 BEGIN_TIME=YEAR2 END_TIME=YEAR$3

judge is a.m.or p.m.

TIME_HOUR1=echo ${BEGIN_TIME:9:2}

cut_log() {
N_DATE1=echo $1 | sed 's/_/ /g'
D_DATE1=echo $2 | sed 's/_/ /g'
E_DATE1=echo $3 | sed 's/_/ /g'
[ 4 ] && N_DATE2=`echo4 | sed 's/_/ /g'[ $5 ] && D_DATE2=echo 5 | sed 's/_/ /g'` [6 ] && E_DATE2=echo $6 | sed 's/_/ /g'
BEGIN=grep -nE "${N_DATE1}|${D_DATE1}|${E_DATE1}" ${LOGFILE} | head -1 | cut -d : -f1
[ "N_DATE2" ] && END=`grep -nE "{N_DATE2}|{D_DATE2}|{E_DATE2}" ${LOGFILE} | tail -1 | cut -d : -f1`

    [ ! -z "${TIME_HOUR1}" ] && if [ ${TIME_HOUR1} -gt 12 ] ; then
            BEGIN1=`grep -nE "${N_DATE1}|${D_DATE1}|${E_DATE1}" ${LOGFILE} |grep " PM " |grep "${E_DATE1}" | head -1 | cut -d : -f1`

            if [ ! -z "${BEGIN1}" ] ; then
            [ "${BEGIN1}" -gt "${BEGIN}" ] ; BEGIN=${BEGIN1}
            fi
    fi

    if [ "$BEGIN" ] && [ -z "$END" ] ; then
            if [ "$N_DATE2" ]; then
                    echo  "${END_TIME}時(shí)間點(diǎn)沒有訪問日志,請(qǐng)重新設(shè)置時(shí)間點(diǎn)."
            else
                    sed -n "${BEGIN},[        DISCUZ_CODE_0        ]quot;p ${LOGFILE} > /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.log
            fi
    elif [ "$END" ];then
            [ "$BEGIN" ] || BEGIN=1
            sed -n "${BEGIN},${END}"p ${LOGFILE} > /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.log
    else
            [ "$END_TIME" != "$YEAR" ] && echo "該時(shí)段 ${BEGIN_TIME}~${END_TIME} 沒有日志."
            [ "$END_TIME" = "$YEAR" ] && echo "該時(shí)段 ${BEGIN_TIME}~now 沒有日志."
    fi

    if [ -s /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.log ]; then
            cd /home/gcweb  &&  tar -zcf ${IPADD}_${TOMCAT}_${DATE}.tar.gz ${IPADD}_${TOMCAT}_${DATE}.log
            rm -f /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.log
            sz /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.tar.gz
            echo "Success to get logs."
            rm -f /home/gcweb/${IPADD}_${TOMCAT}_${DATE}.tar.gz
    fi

}

get_time() {
case "$1" in
4)

             N_DATE=`date -d "$2" +"%Y-%m-%d" 2>/dev/null`
             D_DATE=`date -d "$2" +"%Y/%m/%d" 2>/dev/null`
             E_DATE=`date -d "$2" +"%h %e,_%Y" 2>/dev/null|sed 's/ /_/g'`
             echo $N_DATE $D_DATE $E_DATE
             ;;      

            7)      

             TIME=`echo $2 | awk -F'_' '{print $1,$2}'`
             N_DATE=`date -d "$TIME" +"%Y-%m-%d_%H" 2>/dev/null`
             D_DATE=`date -d "$TIME" +"%Y/%m/%d_%H" 2>/dev/null`
             E_DATE=`date -d "$TIME" +"%h %e,_%Y %l" 2>/dev/null|sed 's/ /_/g'`
             echo  "$N_DATE"  "$D_DATE" "$E_DATE"
            ;;

            9)     

             TIME=`echo $2 | awk -F'_' '{print $1,$2}'`
             N_DATE=`date -d "$TIME" +"%Y-%m-%d_%H:%M" 2>/dev/null`
             D_DATE=`date -d "$TIME" +"%Y/%m/%d_%H:%M" 2>/dev/null`
             E_DATE=`date -d "$TIME" +"%h %e,_%Y %l:%M" 2>/dev/null|sed 's/ /_/g'`
             echo  "$N_DATE" "$D_DATE" "$E_DATE"
            ;;

            *)      
             echo 1
            ;;
   esac

}

check_arguments () {

    if [ "$1" == 1 ] || [ -z  "$1" ] ;then
            echo "你輸入時(shí)間參數(shù)的格式無法識(shí)別, usage: 0108撩嚼、0108_10停士、0108_1020"
            exit 3
    fi

}

check_tomcat () {

    if [ ! -s "${LOGFILE}" ] ;then
      echo "tomcat_name: ${TOMCAT} is not exist"
      echo "you can choose:"
      /bin/ls  /home/gcweb/usr/local/
    fi

    if [ $1 -lt 2 ] || [ ! -s "${LOGFILE}" ];then
            echo "usage: $0 tomcat_name {begin_time|begin_time end_time}"
            exit 2
    fi

}

case "$#" in

0)
    echo "usage: $0 tomcat_name {begin_time|begin_time end_time}"
    exit 1
    ;;

1)
    check_tomcat $#
    ;;

2)

    check_tomcat $#
    len=`echo $2 | awk '{print length($0)}'`
    A_DATE=$(get_time  $len $BEGIN_TIME)
    eval  $( echo $A_DATE |awk '{print "N_DATE="$1,"D_DATE="$2,"E_DATE="$3}')
    check_arguments "${N_DATE}"
    cut_log "${N_DATE}" "${D_DATE}" "${E_DATE}"
    ;;

3)

    check_tomcat $#
    len1=`echo $2 | awk '{print length($0)}'`
    len2=`echo $3 | awk '{print length($0)}'`

    A_DATE=$(get_time ${len1}  $BEGIN_TIME)
    eval  $( echo $A_DATE |awk '{print "N_DATE1="$1,"D_DATE1="$2,"E_DATE1="$3}')
    check_arguments "${N_DATE1}"
    A_DATE=$(get_time ${len2}  $END_TIME)
    eval  $( echo $A_DATE |awk '{print "N_DATE="$1,"D_DATE="$2,"E_DATE="$3}')
    check_arguments "${N_DATE}"
    cut_log ${N_DATE1} ${D_DATE1} ${E_DATE1} "${N_DATE}" "${D_DATE}" "${E_DATE}"
    ;;

*)

    echo "usage: $0 tomcat_name {begin_time|begin_time end_time};你使用的參數(shù)太多哦."
    ;;

esac
【腳本93】數(shù)組

寫一個(gè)腳本讓用戶輸入多個(gè)城市的名字(可以是中文),要求不少于5個(gè)完丽,然后把這些城市存到一個(gè)數(shù)組里恋技,最后用for循環(huán)把它們打印出來。

參考代碼:

!/bin/bash

read -p "請(qǐng)輸入至少5個(gè)城市的名字逻族,用空格分隔:" city
n=echo $city|awk '{print NF}'

if [ $n -lt 5 ]
then
echo "輸入的城市個(gè)數(shù)至少為5"
exit
fi

name=($city)

for i in {name[@]} do echoi
done
【腳本94】批量同步代碼

需求背景是:

一個(gè)業(yè)務(wù)蜻底,有3臺(tái)服務(wù)器(A,B聘鳞,C)做負(fù)載均衡薄辅,由于規(guī)模太小目前并未使用專業(yè)的自動(dòng)化運(yùn)維工具要拂。有新的需求時(shí),開發(fā)同事改完代碼會(huì)把變更上傳到其中一臺(tái)服務(wù)器A上站楚。但是其他2臺(tái)服務(wù)器也需要做相同變更脱惰。

寫一個(gè)shell腳本,把A服務(wù)器上的變更代碼同步到B和C上窿春。

其中拉一,你需要考慮到不需要同步的目錄(假如有tmp、upload谁尸、logs舅踪、caches)

參考代碼:

!/bin/bash

echo "該腳本將會(huì)把A機(jī)器上的/data/wwwroot/www.aaa.com目錄同步到B,C機(jī)器上";
read -p "是否要繼續(xù)?(y|n) "

rs() {
rsync -azP
--exclude logs
--exclude upload
--exclude caches
--exclude tmp
www.aaa.com/ $1:/data/wwwroot/www.aaa.com/

}

if [ REPLY == 'y' -oREPLY == 'Y' ]
then
echo "即將同步……"
sleep 2
cd /data/wwwroot/
rs B機(jī)器ip
rs C機(jī)器ip
echo "同步完成良蛮。"
elif [ REPLY == 'n' -oREPLY == 'N' ]
then
exit 1
else
echo "請(qǐng)輸入字母y或者n"
fi
【腳本95】統(tǒng)計(jì)并發(fā)量

需求背景:

需要統(tǒng)計(jì)網(wǎng)站的并發(fā)量抽碌,并繪圖。
思路:

借助zabbix成圖
通過統(tǒng)計(jì)訪問日志每秒的日志條數(shù)來判定并發(fā)量
zabbix獲取數(shù)據(jù)間隔30s
說明: 只需要寫出shell腳本即可决瞳,不用關(guān)心zabbix配置货徙。

假設(shè)日志路徑為:

/data/logs/www.aaa.com_access.log
日志格式如下:

112.107.15.12 - [07/Nov/2017: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)"
參考代碼:

!/bin/bash

log=/data/logs/www.aaa.com_access.log
t=date -d "-1 second" +%Y:%H:%M:%S

可以大概分析一下每分鐘日志的量級(jí),比如說不超過3000

n=tail -3000 log |grep -c "t"
echo $n
【腳本96】關(guān)閉服務(wù)

在centos6系統(tǒng)里皮胡,我們可以使用ntsysv關(guān)閉不需要開機(jī)啟動(dòng)的服務(wù)痴颊,當(dāng)然也可以使用chkconfig工具來實(shí)現(xiàn)。

寫一個(gè)shell腳本屡贺,用chkconfig工具把不常用的服務(wù)關(guān)閉蠢棱。腳本需要寫成交互式的杀餐,需要我們給它提供關(guān)閉的服務(wù)名字禀忆。

參考代碼:

!/bin/bash

LANG=en
c="1"

while [ ! c == "q" ] do echo -e "\033[35mPlease chose a service to close from this list: \033[0m" chkconfig --list |awk '/3:on/ {print1}'
read -p "Which service to close: " s
chkconfig s off services stop
read -p "If you want's to quit this program, tab "q", or tab "Ctrl c": " c
done
【腳本97】重啟tomcat服務(wù)

在生產(chǎn)環(huán)境中,經(jīng)常遇到tomcat無法徹底關(guān)閉拱镐,也就是說用tomcat自帶shutdown.sh腳本無法將java進(jìn)程完全關(guān)掉量没。所以玉转,需要借助shell腳本,將進(jìn)程殺死殴蹄,然后再啟動(dòng)究抓。

寫一個(gè)shell腳本,實(shí)現(xiàn)上述功能袭灯。徹底殺死一個(gè)進(jìn)程的命令是 kill -9 pid.

參考代碼:

!/bin/bash

功能: 重啟 tomcat 進(jìn)程

要求:對(duì)于tomcat中的某些應(yīng)用刺下,使用shutdown.sh是無法完全停掉所有服務(wù)的 實(shí)際操作中都需要kill掉tomcat再重啟

root can not run this script.

if [ $USER = root ]
then
echo "root cann't run this script!please run with other user!"
exit 1
fi

check the Parameter

if [[ # -ne 1 ]] then echo "Usage:0 tomcatname"
exit 1
fi

only one process can run one time

TMP_FILE_U=/tmp/.tmp.ps.keyword.$USER.956327.txt

echo $TMP_FILE_U

KEYWORD1="0" KEYWORD2="1"

使用賦值會(huì)多fork出一個(gè)進(jìn)程,所以要先重定向到一個(gè)文本,再統(tǒng)計(jì).

ps ux |grep "KEYWORD1"|grep "\<KEYWORD2>"|grep -v "grep" > TMP_FILE_U Pro_count=`catTMP_FILE_U |wc -l`
if [ $Pro_count -gt 1 ]
then
echo "An other process already running ,exit now!"
exit 1
fi

###################################################

begin of the script

###################################################

set the Parameter

TOM=echo $1|sed 's#/##g'
TOMCAT_DIRECTORY=~/usr/local/TOM STARTUP_SCRIPT=TOMCAT_DIRECTORY/bin/startup.sh
TOMCAT_LOG=TOMCAT_DIRECTORY/logs/catalina.out CONF_FILE=TOMCAT_DIRECTORY/conf/server.xml
TEMPFILE=/tmp/.tmpfile.x.89342.c4r3.tmp

check if the tomcat directory exist

if [ ! -d "TOMCAT_DIRECTORY" ] then echo "the tomcat \"TOM" not exist.check again!"
exit 1
fi

log roteta and delete log one week ago

rotate_log(){
TIME_FORMART=(date +%Y%m%d%H%M%S) LOG_DIR=(dirname TOMCAT_LOG) mvTOMCAT_LOG {TOMCAT_LOG}_{TIME_FORMART}
find $LOG_DIR -type f -ctime +7 -exec rm -rf {} ;
}

function start the tomcat

start_tomcat()
{

echo start-tomcat-func

if [ -x "$STARTUP_SCRIPT" ]
then

    rotate_log
    $STARTUP_SCRIPT
    sleep 1
    tail -f $TOMCAT_LOG

else
if [ -e STARTUP_SCRIPT ] then chmod +xSTARTUP_SCRIPT

echo "permition added!"

            if [ -x  "$STARTUP_SCRIPT" ]
            then

                    rotate_log
                    $STARTUP_SCRIPT
                    sleep 1
                    tail -f $TOMCAT_LOG
            else
                    echo "The script not have excute permision,Couldn't add permision to Script!"
                    exit 1
            fi
    else
            echo "error,the script \"startup.sh\" not exist!"
            exit 1
    fi

fi
}

function stop the tomcat

stop_tomcat()
{
rm -rf TEMPFILE ps ux |grep /TOM/ |grep -v "grep /TOM/"|grep java >TEMPFILE
Pro_Count=cat $TEMPFILE|wc -l
PIDS=cat $TEMPFILE|awk '{print $2}'
rm -rf $TEMPFILE

echo $Pro_Count

if [ Pro_Count -eq 0 ] then echo "The tomcat not running now!" else if [Pro_Count -ne 1 ]
then
echo "The have Pro_Count process running,killed!" kill -9 `echoPIDSWC=ps aux | grep "/TOM/" | grep -v "grep /TOM/" | grep java |wc -l[ $WC -ne 0 ] && (echo "kill process failed!";exit 1) else echo "Process killed!" kill -9echo PIDS` WC=`ps aux | grep "/TOM/" | grep -v "grep /TOM/" | grep java |wc -l` [WC -ne 0 ] && (echo "kill process failed!";exit 1)
fi
fi
}

###########################

The main script

###########################

echo -e "are you sure restart TOM?(y or n)" read ANS if [ "ANS"a != ya ]
then
echo -e "bye! \n"
exit 1
fi

stop_tomcat
echo "start tomcat ..."
sleep 2
start_tomcat

end

【腳本98】取消后綴

至少用兩種方法,批量把當(dāng)前目錄下面所有文件名后綴為.bak的后綴去掉稽荧,比如1.txt.bak去掉后為1.txt

假設(shè)取消的后綴為.bak

方法一:

!/bin/bash

for i in ls *.bak
do
mv i `echoi|sed 's/.bak//g'`
done
方法二:

!/bin/bash

for i in ls *.bak
do
newname=echo $i|awk -F '.bak' '{print $1}'
mv inewname
done
【腳本99】域名到期提醒

寫一個(gè)shell腳本橘茉,查詢指定域名的過期時(shí)間,并在到期前一周,每天發(fā)一封提醒郵件捺癞。

思路: 大家可以在linux下使用命令“whois 域名”,如”whois xxx.com”构挤,來獲取該域名的一些信息髓介。

提示: whois命令,需要安裝jwhois包

參考代碼:

!/bin/bash

t1=date +%s
is_install_whois()
{
which whois >/dev/null 2>/dev/null
if [ $? -ne 0 ]
then
yum install -y jwhois
fi
}

notify()
{
e_d=whois $1|grep 'Expiry Date'|awk '{print $4}'|cut -d 'T' -f 1
e_t=date -d "$e_d" +%s
n=echo "86400*7"|bc
e_t1=[e_t-n] if [t1 -ge e_t1 ] && [t1 -lt e_t ] then /usr/local/sbin/mail.py aming_test@163.com "Domain1 will be expire." "Domain 1 expire date ise_d."
fi
}

is_install_whois
notify xxx.com
【腳本100】自動(dòng)增加公鑰

寫一個(gè)shell腳本筋现,當(dāng)我們執(zhí)行時(shí)唐础,提示要輸入對(duì)方的ip和root密碼,然后可以自動(dòng)把本機(jī)的公鑰增加到對(duì)方機(jī)器上矾飞,從而實(shí)現(xiàn)密鑰認(rèn)證一膨。

參考代碼:

!/bin/bash

read -p "Input IP: " ip
ping $ip -w 2 -c 2 >> /dev/null

查看ip是否可用

while [ ? -ne 0 ] do read -p "your ip may not useable, Please Input your IP: " ip pingip -w 2 -c 2 >> /dev/null
done
read -p "Input root's password of this host: " password

檢查命令子函數(shù)

check_ok() {
if [ $? != 0 ]
then
echo "Error!."
exit 1
fi
}

yum需要用到的包

myyum() {
if ! rpm -qa |grep -q "1" then yum install -y1
check_ok
else
echo $1 already installed
fi
}

for p in openssh-clients openssh expect
do
myyum $p
done

在主機(jī)A上創(chuàng)建密鑰對(duì)

if [ ! -f ~/.ssh/id_rsa ] || [ ! -f ~/.ssh/id_rsa.pub ]
then
if [ -d ~/.ssh ]
then
mv ~/.ssh/ ~/.ssh_old
fi
echo -e "\n" | ssh-keygen -t rsa -P ''
check_ok
fi

傳私鑰給主機(jī)B

if [ ! -d /usr/local/sbin/rsync_keys ]
then
mkdir /usr/local/sbin/rsync_keys
fi
cd /usr/local/sbin/rsync_keys
if [ -f rsync.expect ]
then
d=date +%F-%T
mv rsync.expect $d.expect
fi

創(chuàng)建遠(yuǎn)程同步的expect文件

cat > rsync.expect <<EOF

!/usr/bin/expect

set host [lindex $argv 0]

主機(jī)B的密碼

set passwd [lindex $argv 1]
spawn rsync -av /root/.ssh/id_rsa.pub root@$host:/tmp/tmp.txt
expect {
"yes/no" { send "yes\r"; exp_continue}
"password:" { send "$passwd\r" }
}
expect eof
spawn ssh root@$host
expect {
"password:" { send "$passwd\r" }
}
expect "]"
send "[ -f /root/.ssh/authorized_keys ] && cat /tmp/tmp.txt >>/root/.ssh/authorized_keys \r"
expect "]
"
send "[ -f /root/.ssh/authorized_keys ] || mkdir -p /root/.ssh/ \r"
send "[ -f /root/.ssh/authorized_keys ] || mv /tmp/tmp.txt /root/.ssh/authorized_keys\r"
expect "]"
send "chmod 700 /root/.ssh; chmod 600 /root/.ssh/authorized_keys\r"
expect "]
"
send "exit\r"
EOF

check_ok
/usr/bin/expect /usr/local/sbin/rsync_keys/rsync.expect ippassword
echo "OK,this script is successful. ssh $ip to test it"

【腳本101】自動(dòng)封/解封ip

需求背景:

discuz論壇,每天有很多注冊(cè)機(jī)注冊(cè)的用戶洒沦,然后發(fā)垃圾廣告帖子豹绪。雖然使用了一些插件但沒有效果。分析訪問日志申眼,發(fā)現(xiàn)有幾個(gè)ip訪問量特別大瞒津,所以想到可以寫個(gè)shell腳本,通過分析訪問日志括尸,把訪問量大的ip直接封掉巷蚪。

但是這個(gè)腳本很有可能誤傷,所以還需要考慮到自動(dòng)解封這些ip濒翻。

思路:

可以每分鐘分析1次訪問日志屁柏,設(shè)定一個(gè)閾值,把訪問量大的ip用iptables封掉80端口
每20分鐘檢測(cè)一次已經(jīng)被封ip的請(qǐng)求數(shù)據(jù)包數(shù)量有送,設(shè)定閾值淌喻,把沒有請(qǐng)求的或者請(qǐng)求量很小的解封
參考代碼:

! /bin/bash

To block the ip of bad requesting.

Writen by aming 2017-11-18.

log="/data/logs/www.xxx.com.log"
tmpdir="/tmp/badip"

白名單ip,不應(yīng)該被封

goodip="27.133.28.101"

[ -d tmpdir ] || mkdir -ptmpdir

t=date -d "-1 min" +%Y:%H:%M

截取一分鐘以前的日志

grep "t:"log > $tmpdir/last_min.log

把一分鐘內(nèi)日志條數(shù)大于120的標(biāo)記為不正常的請(qǐng)求

awk '{print 1}'tmpdir/last_min.log |sort -n |uniq -c |sort -n |tail |awk '1>120 {print2}'|grep -v "good_ip">tmpdir/bad.ip

d3=date +%M

每隔20分鐘解封一次ip

if [ d3 -eq "20" ] || [d3 -eq "40" ] || [ d3 -eq "00" ] then /sbin/iptables -nvL INPUT|grep 'DROP' |awk '1<10 {print 8}'>tmpdir/good.ip
if [ -s tmpdir/good.ip ] then for ip in `cattmpdir/good.ipdo /sbin/iptables -D INPUT -p tcp --dport 80 -s $ip -j DROP d4=date +%Y%m%d-%H:%M`
echo "d4ip unblock" >>$tmpdir/unblock.ip
done
fi

    #解封后娶眷,再把iptables的計(jì)數(shù)器清零
    /sbin/iptables -Z INPUT

fi

if [ -s tmpdir/bad.ip ] then for ip in `cattmpdir/bad.ipdo /sbin/iptables -A INPUT -p tcp --dport 80 -s $ip -j DROP d4=date +%Y%m%d-%H:%M`
echo "d4ip block" >>$tmpdir/block.ip
done
fi
【腳本102】單機(jī)部署SpringBoot項(xiàng)目

有一臺(tái)測(cè)試服務(wù)器似嗤,經(jīng)常需要部署SpringBoot項(xiàng)目,手動(dòng)部署太麻煩届宠,于是寫了個(gè)部署腳本

腳本代碼:

!/bin/bash

git倉庫路徑

GIT_REPOSITORY_HOME=/app/developer/git-repository

jar包發(fā)布路徑

PROD_HOME=/prod/java-back

應(yīng)用列表

APPS=(app1 app2 app3)

if [ ! -n "$1" ]
then
echo -e "請(qǐng)輸入要發(fā)布的項(xiàng)目烁落!"
exit
fi

cd dir

for((i=0;i<{#APPS[@]};i++)) do echo1 {APPS[i]} if [1 = {APPS[i]} ] then echo -e ===========Enter1=============
cd {GIT_REPOSITORY_HOME}/1
break
fi
done

if [ pwd != {GIT_REPOSITORY_HOME}/1 ]
then
echo -e "輸入的項(xiàng)目名沒有找到!"
exit
fi

echo "==========git切換分之到master==============="
git checkout master

echo "==================git fetch======================"
git fetch

echo "==================git pull======================"
git pull

echo "===========選擇線上環(huán)境編譯并跳過單元測(cè)試===================="
mvn clean package -Dmaven.test.skip=true -Pprod

jar_path={GIT_REPOSITORY_HOME}/1/target/-0.0.1-SNAPSHOT.jar
echo {jar_path} if [ -f{jar_path} ]
then
# backup dest
echo -e "===========jar backup============="
mv {PROD_HOME}/1/
-0.0.1-SNAPSHOT.jar {PROD_HOME}/1/$1-0.0.1-SNAPSHOT.jar.back

# copy
echo "======拷貝編譯出來的jar包拷貝到$PROD_HOME======="
if [ -d ${PROD_HOME}/$1 ]
then
    /bin/cp ${GIT_REPOSITORY_HOME}/$1/target/*-0.0.1-SNAPSHOT.jar  ${PROD_HOME}/$1
else
    mkdir ${PROD_HOME}/$1
    /bin/cp ${GIT_REPOSITORY_HOME}/$1/target/*-0.0.1-SNAPSHOT.jar  ${PROD_HOME}/$1
fi

echo "============停止項(xiàng)目============="
jar_name=`jps |awk -F" " '{ print $2 }'| egrep ^$1.*jar$`
pid=`jps |grep ${jar_name} | awk -F" " '{ print $1 }'`
echo ${pid}
kill -15 ${pid}

echo "================sleep 10s========================="
for i in 1 2 3 4 5 6 7 8 9 10
do
    echo ${i}"s"
    sleep 1s
done

echo "============啟動(dòng)項(xiàng)目============="
nohup java -jar ${PROD_HOME}/$1/*-0.0.1-SNAPSHOT.jar > /dev/null 2>&1 &
echo -e "===========Deploy Success============="

else
echo -e "===========Deploy Error============="
fi

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末豌注,一起剝皮案震驚了整個(gè)濱河市伤塌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌轧铁,老刑警劉巖每聪,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡药薯,警方通過查閱死者的電腦和手機(jī)绑洛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來童本,“玉大人真屯,你說我怎么就攤上這事∏钣椋” “怎么了绑蔫?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)泵额。 經(jīng)常有香客問我配深,道長(zhǎng),這世上最難降的妖魔是什么嫁盲? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任篓叶,我火速辦了婚禮,結(jié)果婚禮上亡资,老公的妹妹穿的比我還像新娘澜共。我一直安慰自己,他們只是感情好锥腻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布嗦董。 她就那樣靜靜地躺著,像睡著了一般瘦黑。 火紅的嫁衣襯著肌膚如雪京革。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天幸斥,我揣著相機(jī)與錄音匹摇,去河邊找鬼。 笑死甲葬,一個(gè)胖子當(dāng)著我的面吹牛廊勃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播经窖,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼坡垫,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了画侣?” 一聲冷哼從身側(cè)響起冰悠,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎配乱,沒想到半個(gè)月后溉卓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體皮迟,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年桑寨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伏尼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尉尾,死狀恐怖烦粒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情代赁,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布兽掰,位于F島的核電站芭碍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏孽尽。R本人自食惡果不足惜窖壕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杉女。 院中可真熱鬧瞻讽,春花似錦、人聲如沸熏挎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坎拐。三九已至烦磁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哼勇,已是汗流浹背都伪。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留积担,地道東北人陨晶。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像帝璧,于是被迫代替她去往敵國(guó)和親先誉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容