shell脚本示例

发布时间 2023-10-20 17:15:14作者: 龙泉寺老方丈

1. 编写脚本技巧

#!/bin/bash
#date: yyyy-mm-dd
#author: shaochong

#启用环境变量
source /etc/profile
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/apps/bin/"

#set -xe  # x:显示执行脚本详情 e:状态码非0退出脚本

#脚本中使用到未声明变量时退出脚本
#set -o nounset 或 set-u

#readonly声明静态变量,即定义后无法修改
#readonly Ftp_dir=/data/ftp_dir


#cd `dirname $0`

2. 脚本:color

#!/bin/bash
Red='\E[1;31m'
Green='\E[1;32m'
Yellow='\E[1;33m'
Blue='\E[1;34m'
Pink='\E[1;35m'
Res='\E[0m'

usage()
{
echo "USAGE:$0 {red|green|yellow|blue|pink}" contents && exit 1
}

color()
{
case $1 in
  "red")
   echo -e "${Red}$2 ${Res}";;
  "green")
   echo -e "${Green}$2 ${Res}";;
  "yellow")
   echo -e "${Yellow}$2 ${Res}";;
  "blue")
   echo -e "${Blue}$2 ${Res}";;
  "pink")
   echo -e "${Pink}$2 ${Res}";;
   *)
   usage
   ;;
esac
}

main() 
{
if [ $# -ne 2 ];then
    usage
fi
    color $1 $2
}
main $*


3. 脚本:for循环嵌套

# mkdir -p /data/{2018..2020}/{1..12}/{1..31}

'''
#!/bin/bash
#date:2020/08/11
#author:shao
#for循环嵌套统计每个年份目录下的每个月份目录下的每天的目录文件数量
File=/tmp/shao.txt
[ ! -s $File ] || > $File

PaTh=/data
for Year in {2018..2020};do
  for Month in `ls $PaTh/$Year`;do  
    cd $PaTh/$Year/$Month
    for Day in `ls`;do
      echo "[ $Year-$Month-$Day ]" >> $File
      ls $Day | wc -l >> $File
    done
  done
done
'''

4. 脚本:检测网址联通性

#!/bin/bash
#检测网址连通性
[ -f /etc/init.d/functions ] && . /etc/init.d/functions
array=(
http://www.baidu.com
http://www.taobao.com
http://www.google.com
http://www.51cto.com
http://10.0.0.1
)
wget_ip() {
wget -T 5 -t 1 --spider --no-check-certificate $1 &> /dev/null
return $?
}
main() {
for i in ${array[*]}
do
    wget_ip $i
  if [ $? -eq 0 ];then
    action "curl $i" /bin/true
  else
    action "curl $i" /bin/false
  fi
done
}
main

5. 脚本:密钥分发

#!/bin/bash
#批量分发密钥
#by: Shaochong
#ssh-keygen -t rsa  -f ~/.ssh/id_rsa -P ""
Port=2200
User=root
Passwd=abc123
for ip in 192.168.1.{10..20};do
    ping -c2 $ip &> /dev/null
    if [ $? -ne 0 ];then
        echo "$ip is down"
        continue
    else
        echo "$ip is up"
        sshpass -p $Passwd ssh-copy-id -i -p $Port "-o StrictHostKeyChecking=no" $User@$ip  &> /dev/null
        if [ $? -eq 0 ];then
            echo "$ip 分发公钥secceed"
        else
            echo "$ip 分发公钥failed"
        fi
    fi
done

6. 生产脚本:TCP连接数监控-统计TCP11种状态连接数

#!/bin/bash
#date:   20191212
#author: shaochong
usage()
{
echo "Usage $0 {key}" && exit 1
}

tcp_connect()
{
SUM=$(ss -ant | awk 'NR>1 {++s[$1]} END {for(i in s) print i,s[i]}' | grep -i $1  2> /dev/null | awk '{print $2}')

rpm -qa | grep iproute &> /dev/null
[[ $? -eq 0 ]] || exit 2

if [ ! -z $SUM ]
   then
       [ $# -eq 1 ] && echo $SUM || usage
   else
       [ $# -eq 1 ] && echo 0 || usage
fi
}

tcp_connect $*

7. 生产脚本:日志监控-检查日志刷新时间

#!/bin/bash

#Servertime
Year=`date +%Y`
Month=`date +%m`
Day=`date +%d`

#Logtime
Logtime_Year=$(stat $1 | awk -F"(:|-| )" '/Change:/{print$3}')
Logtime_Month=$(stat $1 | awk -F"(:|-| )" '/Change:/{print$4}')
Logtime_Day=$(stat $1 | awk -F"(:|-| )" '/Change:/{print$5}')


#Operation
Month_Value=$(echo $Month $Logtime_Month | awk '{print $1-$2}')
Day_Value=$(echo $Day $Logtime_Day | awk '{print $1-$2}')

#判断年份是否相同
if [ $Year -eq $Logtime_Year ]
  then :
else
  echo 1
  exit 1
fi

#判断月份是否相差一个月之内
if [ $Month_Value -le 1 ]
  then :
else
  echo 2
  exit 2
fi

#判断日期是否相差三天之内
if [ $Day_Value -le 2 -a $Day_Value -ge 0 -a $Month -eq $Logtime_Month ]
  then echo 0
elif [ $Day_Value -le -27 -a $Day_Value -ge -30 ]
  then echo 0
else 
  echo 3
fi

8. 生产脚本-mq队列监控

#!/bin/bash
#set crontab (rabbitmqctl list_quenens > /tmp/rabbitmq_queues.txt)
File=/tmp/rabbitmq_queues.txt
Queue_Num=$(awk 'NR>3' $File | grep $1 2>/dev/null | awk '{print $2}')
Queue=$(awk 'NR>3' $File | grep $1 2>/dev/null | wc -l)
if [ ${#Queue_Num} -eq 1 -a $Queue -eq 1 ];then
    echo $Queue_Num
else
    echo "Usage $0 (Type the correct value)"
fi

9. 脚本:处理ftp文件

'''
#!/bin/bash
declare -A ftp_cfg
ftp_cfg=([IP]="127.0.0.1" [PORT]="21" [USER]="test1" [PASSWORD]="abc@123" [FTP_DIR]="/var/ftp/test1"  [HOST_DIR]="/tmp/ftp_dir/upload_ftp")
nowTime=$(date +"%F %T")               
logFileName="$(date +%F).txt"          
logFilePath="/tmp/ftp_dir/ftp_logs"

sendFileToFtp()
{
  ftp -n << EOF
  open ${ftp_cfg[IP]} ${ftp_cfg[PORT]}
  user ${ftp_cfg[USER]} ${ftp_cfg[PASSWORD]}
  cd   ${ftp_cfg[FTP_DIR]}
  binary
  lcd  ${ftp_cfg[HOST_DIR]}
  put  $1 $2
  rename $2 $3
  close
  bye
EOF
}

operateFile()
{
  FileArry=$(ls ${ftp_cfg[HOST_DIR]})
  touch $logFilePath/$logFileName
  cd ${ftp_cfg[HOST_DIR]}
  for file in ${FileArry[*]};do
    echo $file | egrep '.now|.done'
    if [ $? -ne 0 ];then
      doneFileArray[i]="$file"
      let i++
      mv $file "$file.done"
      echo -e "[ ${nowTime} ]\t name file name $file to $file.done" >> $logFilePath/$logFileName
    else
      echo "not done file $file"
    fi
  done
  for file in ${doneFileArray[*]};do
    sendFileToFtp "$file.done" "$file.now" $file
    echo -e "[ ${nowTime} ]\t send file $file to ${ftp_cfg[FTP_DIR]}" >> $logFilePath/$logFileName
  done
}
operateFile
'''

#用途:
将本地路径下不包含后缀".done|.now"的文件 先增加后缀".done",然后上传到将".done"文件上传到ftp命名后缀改为".now",然后将后缀去掉

10. 脚本:数组案例

# 随机生成10个数字,并打印最大的数字
'''
#!/bin/bash
for I in {0..9};do
  ARRAY[$I]=$RANDOM
  echo -en "${ARRAY[$I]}\t"
#  sleep 1
done

declare -i MAX=${ARRAY[0]}
INDEX=$[${#ARRAY[*]}-1]

for I in `seq 1 $INDEX`;do
  if [ $MAX -lt "${ARRAY[$I]}" ];then
    MAX=${ARRAY[$I]}
  fi
done
echo -e "\n\nMax_Num:$MAX"
'''


# 交互输入,根据输入输出指定个数的数字,并不重复
#declare -i xxx //声明整数型变量
#declare -r xxx //设置变量为只读
#declare -a xxx //声明数组变量
'''
#!/bin/bash
declare -i NUM
declare -a ARRAY

usage()
{
echo "USAGE:$0 num range_num(num Is not greater than range_num)" && exit 1
}

check() 
{
  for num in `seq 1 ${#ARRAY[*]}`;do
    if [ "$1" -eq "${ARRAY[$num]}" ];then
      return 1
    fi
  done
}

output() 
{
for i in `seq 1 $1`;do
  while true;do
    NUM=$[$RANDOM%$2+1]
    check $NUM
    [[ $? -eq 0 ]] &&  break
  done
  ARRAY[$i]=$NUM
  echo "${ARRAY[$i]}"
done
}

main()
{ 
if [ $# -ne 2 -o $1 -gt $2 ];then 
  usage
else
   output $1 $2
fi
}

main $*


11. while read line判断两个文件夹相同的文件并打包

#!/bin/bash
Src=source
Dst=dest
[ ! -d $Src -o ! -d $Dst ] && exit 1

find ./$Src -type f | awk -F"$Src/" '{print $2}' > source.txt
find ./$Dst -type f | awk -F"$Dst/" '{print $2}' > dest.txt

while read i;do
  while read q;do
    if [ "$(md5sum source/$i | awk '{print $1}')" = "$(md5sum dest/$q | awk '{print $1}')" ];then
      echo $Dst/$i >> bak.txt
    fi
  done < source.txt
done < dest.txt

tar zcvf backup.tar.gz `cat bak.txt`
rm -f bak.txt source.txt dest.txt