-------------案例1--------------------

###需求

## 遍历/data/目录下的txt文件

## 将txt 文件做一个备份

## 备份的文件名增加一个年月日的后缀,比如将holy.txt备份为holy.txt_20240515


#!/bin/bash

# author: holy

# version: v1

# date: 2024-05-15


#定义后缀遍历,注意下面这个 ``(反引号)的含义

suffix=`date +%Y%m%d`


##找到/data/目录下的txt文件,用for循环遍历

for f in `find /data/ -type f -name "*.txt"`

do  

   echo "备份文件$f"

   cp ${f} ${f}_${suffix}

done

-------------案例2--------------------

## 需求

## 创建10个用户,并给他们设置随机密码,密码记录到一个文件里

## 用户从user_00 到 user_09

## 密码要求:包含大小写字母以及数字,密码长度15位

#!/bin/bash

# author: holy

# version: v1

# date: 2024-05-15


## 先查看/tmp/userinfo.txt文件是否存在,存在的话先删除,以免影响到本次脚本执行结果

if [ -f /tmp/userinfo.txt ]

then

  rm -f /tmp/userinfo.txt

fi

## 判断mkpasswd命令在不在,我们用该命令来生成随机字符串,也就是用户密码

if ! which mkpasswd

then

   ##在这里,我们假定系统就是CentOS或者Rocky,可以用yum安装包

  yum install -y expect

fi

#借助seq 生成00  到 09 ,10个数的队列

for i in `seq -w 0 09`

do

  ##每次生成一个随机字符串,将字符串赋值给p变量,这个就是用户的密码了

  ##mkpasswd命令默认生成的字符串会包含大小写字母和数字和特殊符号

  ##如果不要求特殊符合,可以加-s 0 来限定不使用特殊符号

  p=`mkpasswd -l 15 -s 0`

  useradd user_${i} && echo "${p}"| passwd --stdin user_${i}

  #useradd user_$i && echo "$p|passwd --stdin user_$i"

  echo "user_${i} ${p}" >> /tmp/userinfo.txt

done





-------------案例3--------------------

##需求:

##写一个检测脚本,用来检测本机所有磁盘分区读写是否都正常

##提示: 可以遍历所有挂载点,然后新建一个测试文件,

#!/bin/bash

#author: holy

#version: v1

#date: 2024-05-14


for mount_p in `df |sed '1d' | grep -v 'tmpfs' | awk '{print $NF}'`

do

   touch $mount_p/testfile && rm -f $mount_p/testfile

   if [ $? -ne 0 ]

   then

       echo "$mount_p 读写有问题"

   else

       echo "$mount_p 读写正常"

   fi

done




-------------案例4--------------------

## 脚本需求:

## 检查/data/wwwroot/app 目录下所有文件和目录,看是否满足下面条件

## 1) 所有文件权限为644

## 2) 所有目录为755

## 3) 文件和目录所有者为www,所属组为root

## 如果不满足,改成符合要求

#!/bin/bash

# author: holy

# version: v1

# data: 2024-05-14


cd /data/wwwroot/app


for f in `find .`

do  

   ##看文件权限

   f_p=`stat -c %a $f`

   ##查看文件所有者

   f_u=`stat -c %U $f`

   ##查看文件所属组

   f_g=`stat -c %G $f`

 

   ##判断是否为目录

   if [ -d $f ]

   then  

      [ $f_p != '755' ] && chmod 755 $f

   else

      [ $f_p != '644' ] && chmod 644 $f

   fi

   ## &&用在两条命令中间,可以起到if判断的作用

   ## 当第一条命令成功,才会执行后面的命令

   [ $f_u != 'www' ] && chown www $f

   [ $f_g != 'root' ] && chown :root $f

done

-------------案例5--------------------

##需求

## 在一个目录/data/att/, 该目录下有数百个子目录

## 比如/data/att/holy, /data/att/linux

## 然后再深入一层为以日期命名的目录,例如 /data/att/holy/20240515

## 每天会生成一个日期新目录,由于/data所在磁盘快满了

## 所以需要将老文件(一年以前的) 挪到另外一个目录/data1/att下

## 示例: mv /data/att/holy/20240514  /data1/att/holy/20240514

## 挪完之后,还需要做软链接

## 示例: ln -s /data1/att/holy/20240514 /data/att/holy/20240514

## 写一个脚本,要求/data/att/下所有子目录都要按此操作

## 脚本会每天01:00执行一次,任务计划无需考虑,只需要写脚本即可

## 提醒:要确保老文件成功挪到/data1/att 下之后才能做软链接,需要有日志


#!/bin/bash

# author: holy

# version: holy

# date: 2024-05-15


## 先定义一个main函数,目的是为了后面调用函数,方便记录日志

main()

{

 cd /data/att


 ## 遍历第一层目录

 for dir in `ls`

 do

    ## 遍历第二层目录,用find只找当前目录下一年以前的子目录

    for dir2 in `find $dir -maxdepth 1 -type d -mtime +365`

    do

        ## 将目标目录下的文件同步到/data1/att/目录下,注意这里的-R 可以自动创建目录结构  

        rsync -aR $dir2/  /data1/att/

        if [ $? -eq 0 ]

        then

            ## 如果同步成功,会将/data/att下的目录删除

            rm -rf $dir2

            echo "/data/att/$dir2 移动成功"

            ## 做软链接

            ln -s /data1/att/$dir2 /data/att/$dir2 && \

            echo "/data/att/$dir2 成功创建软链接"

            echo

         else

            echo "/data/att/$dir 未移动成功"

         fi

      done

  done

}

main & > /tmp/move_old_data_`date +%F`.log

-------------案例6--------------------

## 脚本需求

## 监控系统负载,负载超过10,小记录系统状态信息

## 1、系统负载命令使用uptime看过去1分钟的平均负载

## 2、系统状态使用如下工具标记: top、vmstat、 ss

## 3、要求每隔30s监控一次

## 4、系统状态信息需要保存到/opt/logs下面。保留一个月,文件名建议带有 `date +%s `后缀或者前缀


#!/bin/bash

# author: holy

# version: v1

# date: 2024-05-14


## 首先看/opt/logs目录在不在,不在就创建

[ -d /opt/logs ] || mkdir -p /opt/logs


##while死循环

while :

do

  ## 获取系统1分钟的负载,并且只取小数点前面的数字

  load=`uptime | awk -F 'average:' '{print $2}' | cut -d',' -f1 | sed 's/ //g'| cut -d'.' -f1`

  if [ $load -gt 10 ]

  then

       ##分辨记录top、vmstat和ss命令的执行结果

       top -bn1|head -n 100 > /opt/logs/top.`date +%s`

       vmstat 1 10 > /opt/logs/vmstat.`date +%s`

       ss -an > /opt/logs/ss.`date +%s`

   fi

   ## 休眠30s

   sleep 30

   ## 找到30天以前的日志文件删除掉

   find /opt/logs \( -name "top* -o -name "vmstat*"" -o -name "ss*" \) -mtime +30 | xargs rm -f  

done

-------------案例7--------------------

##需求

## 有一台服务器作为web应用,有一个目录(/data/web/attachment)

## 不定时地会被用户上传新的文件,但是不知道什么时候会上传

## 所以,需要我们每5分钟做一次检测是否有新文件生成

## 写一个shell脚本去完成检测,检测完成后若是有新文件

## 还需要将新文件的列表输出到一个按年、月、日、时、分为名字的日志里

## 思路:每5分钟检测一次,那肯定要有一个计划任务,每五分钟去执行一次

## 脚本检测的时候,就是使用find命令查找5分钟内有过更新的文件

## 若是有更新,那这个命令会输出东西,否则是没有输出的,可以把输出结果的行数作为比较对象,看是否大于0


#!/bin/bash

# author: holy

# version: v1

# date: 2024-5-15


## 日志文件名,包含年月日时分

d=`date +%Y%m%d%H%M`

basedir=/data/web/attachment


## find 找到5分钟之内新产生的文件,并把文件列表写入一个文件里

find $basedir/ -type f -mmin -5 > /tmp/newf.txt


## 如果文件里有内容,把文件改名字,即我们要的文件列表日志文件

if [ -s /tmp/newf.txt ]; then

     /bin/mv /tmp/newf.txt /tmp/$d

     echo "有文件输出"

else

 echo "没有文件输出"

fi




-------------案例8--------------------

## 需求

## 输入一个数字,然后运行对应的一个命令。

## 显示命令如下:

## *cmd meau** 1-date 2-ls 3-who 4-pwd

## 当输入1时,会运行date,输入2时运行ls,依此类推


##

#!/bin/bash

# author: holy

# version: v1

# date: 2024-05-15


## 先把提示语打印出来

echo "*cmd meau** 1-date 2-ls 3-who 4-pwd"


## 使用死循环,目的是为了当用户输入的字符并非要求的字符时,

## 不能直接退出脚本,而是再次重新开始


while :

do

  ##然后使用read实现和用户交互,提示让用户输入一个数字

  read -p "plsase input a number 1-4: " n  

  case $n  in

     1)

        echo "显示时间"

        date

        ## 之所以要break,是因为当用户执行完命令就要退出脚本了

        break

        ;;

     2)

        echo "列出当前目录列表"

        ls

        break

        ;;

     3)

        echo "显示当前活动用户"

        who

        break

        ;;

     4)

        echo "显示当前路径"

        pwd

        break

        ;;

     *)

       ##如果输入的并不是1-4的数字,提示出错

       echo "Wrong input,try again!"

       ;;

    esac

done

-------------案例9--------------------

## 需求

## 写一个脚本,执行后,打印一行提示 "Please input a number:"

## 要求用户输入数值,然后打印出该数值,然后再>次要求用户输入数值

## 知道用户输入 “end” 停止


#!/bin/bash

# author: holy

# version: v1

# date: 2024-05-15


while :

do  

    ## 提示语

    read -p "Please input a number:(Input "end" to quit)" n

    ## 使用sed将用户输入的字符串中数字替换为空,如果是纯数字,那么num的值为1

    ## 为什么是1而不是0呢,因为wc -c 会把回车也标记为1个字符

    num=`echo $n | sed -r 's/[0-9]//g' | wc -c`

    if [ $n == "end" ]

    then  

        exit

    fi

    if [ $num -ne 1 ]

    then

          echo "What you input is not a number! Try again!"

    else

          echo "The number you entered is: $n"

    fi

done

-------------案例10--------------------

## 脚本需求:

## 监控某站点访问是否正常

## 1、可以将访问的站点以参数的形式提供,例如 sh xxx.sh

## 2、状态码为2xx或者3xx表示正常

## 3、正常时echo正常,不正常时echo不正常

##

##

#!/bin/bash

# author:holy

# version: v1

# date: 2024-05-14


if ! which curl &>/dev/null

then

  echo "本机没有安装curl"

  ##这里假设系统为CentOS/RHEL/Rockey

  yum install -y curl

  if [ $? -ne 0 ]

  then  

     echo "没有安装成功curl"

     exit 1

  fi

fi