-------------案例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