我们下一阶段将学习python语言,python是目前很流行且相对成熟的语言,程序员社区建设也好,各种库也成熟,如果有群友对这部分很熟悉,可以免学跳过。

再学习python语言前,我们要通过若干大作业来总结前一段的学习任务。

第一个大作业,写一个自动化压缩目录下符合一定规律文件的自动化脚本

任务1:写一个模拟产生日志的脚本

假定你的工作目录是/data/。子工作目录是/data/work1/、/data/work2/ 和/data/work3。你需要写一个脚本,每个小时在以上三个目录中分别创建文件。例如
/data/work1/readme.20200425_09
/data/work1/readme.20200425_10
/data/work1/readme.20200425_11

/data/work2/pubme.20200425_09
/data/work2/pubme.20200425_10
/data/work2/pubme.20200425_11

/data/work3/iconme.20200425_09
/data/work3/iconme.20200425_10
/data/work3/iconme.20200425_11

并在文件内写入生产文件的时间(年月日时分秒)。
我们假定这个程序是线上环境输出的每个小时应用程序产生的日志。且假定这个日志文件非常大(实际生产环境会很大,我们做实验其实很小,但假定这个文件很大需要压缩)。

  1. 编写脚本文件 ```bash [root@localhost data]# cat /gen.sh

    !/bin/bash

base_path=/data file_prefixs=(“readme” “pubme” “iconme”)

for i in {1..3} do file_folder=”$base_path/work$i” mkdir -p $file_folder

  1. file_prefix=${file_prefixs[i-1]}
  2. file_name="$file_prefix.$(date "+%Y%m%d_%H")"
  3. echo $(date "+%Y-%m-%d %H:%M:%S") > "$file_folder/$file_name"

done

  1. 2. 添加定时任务
  2. ```bash
  3. [root@localhost data]# crontab -l
  4. * */1 * * * /bin/bash /gen.sh
  5. [root@localhost data]# systemctl restart cron
  1. 测试 ```bash [root@localhost data]# cat gen_test.sh

    !/bin/bash

base_path=/data

清除所有文件

rm -rf $basepath/* date_time=`date “+%Y%m%d%H”`

./gen.sh

file_prefixs=(“readme” “pubme” “iconme”)

for i in {1..3} do file_folder=”$base_path/work$i”

  1. # 检查是否创建了3个文件。
  2. if [ ! -e $file_folder ]
  3. then
  4. echo $file_folder not exists
  5. fi
  6. # 检查文件是否创建文件
  7. file_prefix=${file_prefixs[i-1]}
  8. file_path="$file_folder/$file_prefix.$date_time"
  9. if [ ! -e $file_path ]
  10. then
  11. echo $file_path not exists
  12. fi

done

  1. <a name="eS948"></a>
  2. ## 任务2:写一段脚本自动压缩这个目录下每个带有时间特征的文件。
  3. 功能如下:<br />能够每隔5分钟启动一次,判断/data/目录下所有子目录中是否产生了带有时间特征的文件,且没有压缩,如果有,放过最新的这一个不压缩,把其他的都压缩了。<br />那么假定这个脚本启动看到上面那个例子将会压缩成如下情况<br />/data/work1/readme.20200425_09 <br />/data/work1/readme.20200425_09.7z<br />/data/work1/readme.20200425_10<br />/data/work1/readme.20200425_10.7z<br />/data/work1/readme.20200425_11 (放过最新的这个不压缩)<br />
  4. /data/work2/pubme.20200425_09 <br />/data/work2/pubme.20200425_09.7z<br />/data/work2/pubme.20200425_10<br />/data/work2/pubme.20200425_10.7z<br />/data/work2/pubme.20200425_11 (放过最新的这个不压缩)<br />
  5. /data/work3/iconme.20200425_09 <br />/data/work3/iconme.20200425_09.7z<br />/data/work3/iconme.20200425_10<br />/data/work3/iconme.20200425_10.7z<br />/data/work3/iconme.20200425_11 (放过最新的这个不压缩)<br /><br />主要:主要脚本代码中不要有硬编码,不要出现work1,work2,work3这种。否则如果以后/data/目录下新增加一个work4,还需要手动修改这个脚本,要做到,无论在这个目录下加入什么子目录,这个脚本可以自动实别子目录下带时间特征的文件进行压缩。
  6. 1. 编写脚本
  7. ```bash
  8. [root@localhost data]# cat compress.sh
  9. #!/bin/bash
  10. base_path=/data
  11. compress() {
  12. dir_path=$1
  13. for file_name in `ls -l $dir_path | grep ^- | grep -v '7z$' | awk '{print $9}' | sort -r | awk 'NR>1'`
  14. do
  15. file_path="$dir_path/$file_name"
  16. if [ -e "$file_path.7z" ]
  17. then
  18. echo "$file_path.7z exists"
  19. continue
  20. fi
  21. if [ -n "`lsof -c 7z | grep $file_path.7z`" ]
  22. then
  23. echo "$file_path is compressing"
  24. continue
  25. fi
  26. echo "$file_path start compressing"
  27. 7z a $file_path.7z $file_path > /dev/null &
  28. done
  29. }
  30. for file_name in `ls -l $base_path | grep ^d | awk '{print $9}'`
  31. do
  32. file_path="$base_path/$file_name"
  33. compress $file_path
  34. done
  1. 添加定时任务 ```bash [root@localhost data]# crontab -l /5 * /bin/bash /compress.sh

[root@localhost data]# systemctl restart cron

  1. 3. 测试
  2. ```bash
  3. [root@localhost data]# cat compress_test.sh
  4. #!/bin/bash
  5. base_path=/data
  6. # 清空子文件夹
  7. for file_name in `ls -l $base_path | grep ^d | awk '{print $9}'`
  8. do
  9. file_path="$base_path/$file_name"
  10. rm -rf $file_path/*
  11. done
  12. # 创建一个大文件,延长压缩时间
  13. if [ ! -e "$base_path/temp" ]
  14. then
  15. echo creating large file
  16. for i in {1..5}
  17. do
  18. head -n 1000000 /dev/urandom >> $base_path/temp
  19. done
  20. fi
  21. # 创建6个文件夹,每个文件夹中添加3个大文件。
  22. file_prefixs=("readme" "pubme" "iconme" "readme" "pubme" "iconme")
  23. for i in {1..6}
  24. do
  25. file_folder="$base_path/work$i"
  26. `mkdir -p $file_folder`
  27. file_prefix=${file_prefixs[i-1]}
  28. for j in {1..3}
  29. do
  30. file_name="$file_prefix.$(date -d "-$j hour" "+%Y%m%d_%H")"
  31. file_path="$file_folder/$file_name"
  32. if [ ! -e $file_path ]
  33. then
  34. cp -f $base_path/temp $file_path
  35. fi
  36. done
  37. done
  38. # 多次执行压缩脚本,查看是否会重复压缩。
  39. for i in {1..5}
  40. do
  41. ./compress.sh
  42. sleep 10
  43. done

执行脚本后打开另一个终端,查看当前 7z 进程

  1. # 多次查看进程没有发现重复压缩的文件。而且目录 work4 work5 work6 下的文件也都被压缩了。最新的文件 readme.20200504_17 没有被压缩。
  2. [root@localhost data]# ps -ef | grep 7z
  3. chao 16510 1 33 17:05 ? 00:00:51 /usr/lib/p7zip/7z a /data/work1/readme.20200504_15.7z /data/work1/readme.20200504_15
  4. chao 16517 1 32 17:05 ? 00:00:49 /usr/lib/p7zip/7z a /data/work1/readme.20200504_14.7z /data/work1/readme.20200504_14
  5. chao 16531 1 31 17:05 ? 00:00:48 /usr/lib/p7zip/7z a /data/work2/pubme.20200504_15.7z /data/work2/pubme.20200504_15
  6. chao 16538 1 32 17:05 ? 00:00:49 /usr/lib/p7zip/7z a /data/work2/pubme.20200504_14.7z /data/work2/pubme.20200504_14
  7. chao 16552 1 31 17:05 ? 00:00:47 /usr/lib/p7zip/7z a /data/work3/iconme.20200504_15.7z /data/work3/iconme.20200504_15
  8. chao 16559 1 31 17:05 ? 00:00:48 /usr/lib/p7zip/7z a /data/work3/iconme.20200504_14.7z /data/work3/iconme.20200504_14
  9. chao 16575 1 31 17:05 ? 00:00:47 /usr/lib/p7zip/7z a /data/work4/readme.20200504_15.7z /data/work4/readme.20200504_15
  10. chao 16584 1 32 17:05 ? 00:00:49 /usr/lib/p7zip/7z a /data/work4/readme.20200504_14.7z /data/work4/readme.20200504_14
  11. chao 16598 1 32 17:05 ? 00:00:48 /usr/lib/p7zip/7z a /data/work5/pubme.20200504_15.7z /data/work5/pubme.20200504_15
  12. chao 16605 1 31 17:05 ? 00:00:48 /usr/lib/p7zip/7z a /data/work5/pubme.20200504_14.7z /data/work5/pubme.20200504_14
  13. chao 16619 1 31 17:05 ? 00:00:48 /usr/lib/p7zip/7z a /data/work6/iconme.20200504_15.7z /data/work6/iconme.20200504_15
  14. chao 16626 1 32 17:05 ? 00:00:48 /usr/lib/p7zip/7z a /data/work6/iconme.20200504_14.7z /data/work6/iconme.20200504_14
  15. chao 17655 17134 0 17:07 pts/18 00:00:00 grep --color=auto 7z
  16. # 查看压缩过后文件的MD5
  17. [root@localhost data]# md5sum /data/work1/readme.20200504_16
  18. 14e86bbf03c4d98c02cb72ed7b050fe0 /data/work1/readme.20200504_16
  19. [root@localhost data]# 7z x /data/work1/readme.20200504_16.7z -o/tmp/
  20. 7-Zip [64] 9.20 Copyright (c) 1999-2010 Igor Pavlov 2010-11-18
  21. p7zip Version 9.20 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,4 CPUs)
  22. Processing archive: /data/work1/readme.20200504_16.7z
  23. Extracting readme.20200504_16
  24. Everything is Ok
  25. Size: 1279203754
  26. Compressed: 1296522502
  27. # md5 一致压缩正确
  28. [root@localhost data]# md5sum /tmp/readme.20200504_16
  29. 14e86bbf03c4d98c02cb72ed7b050fe0 /tmp/readme.20200504_16

任务3:写一段脚本自动删除5个小时以前的已经压缩好的原始文件。

例如现在时刻是2020年4月25日15点。那么这个脚本就需要负责删除
/data/work1/readme.20200425_09,/data/work2/pubme.20200425_09和/data/work3/iconme.20200425_09。即原始日志只留压缩版本,不留非压缩版本。
当然这个5是可配置的。

  1. [root@localhost data]# cat clean.sh
  2. #!/bin/bash
  3. base_path=/data
  4. age=${1-5}
  5. start_time=`date -d "-$age hour" "+%Y%m%d_%H"`
  6. clean() {
  7. dir_path=$1
  8. for file_name in `ls -l $dir_path | grep ^- | grep -v 7z$ | awk '{print $9}' | sort -r | awk -F . '{if(\$2 < "'$start_time'" )print \$0}'`
  9. do
  10. file_path="$dir_path/$file_name"
  11. if [ -n "`lsof -c 7z | grep $file_path.7z`" ]
  12. then
  13. echo "$file_path is compressing"
  14. continue
  15. fi
  16. if [ -e "$file_path.7z" ]
  17. then
  18. echo "remove $file_path"
  19. rm $file_path
  20. fi
  21. done
  22. }
  23. for file_name in `ls -l $base_path | grep ^d | awk '{print $9}'`
  24. do
  25. file_path="$base_path/$file_name"
  26. clean $file_path
  27. done
  1. 测试 ```bash

    !/bin/bash

base_path=/data

清空子文件夹

for file_name in ls -l $base_path | grep ^d | awk '{print $9}' do file_path=”$base_path/$file_name” rm -rf $file_path/* done

创建6个文件夹,每个文件夹中添加10个大文件。如果成功,最后会剩下5个文件

file_prefixs=(“readme” “pubme” “iconme” “readme” “pubme” “iconme”) for i in {1..6} do file_folder=”$base_path/work$i” mkdir -p $file_folder file_prefix=${file_prefixs[i-1]}

  1. for j in {1..10}
  2. do
  3. file_name="$file_prefix.$(date -d "-$j hour" "+%Y%m%d_%H")"
  4. file_path="$file_folder/$file_name"
  5. echo $(date "+%Y-%m-%d %H:%M:%S") > $file_path
  6. done
  7. file_name="$file_prefix.$(date -d "-11 hour" "+%Y%m%d_%H")"
  8. file_path="$file_folder/$file_name"
  9. cp -f $base_path/temp $file_path

done

压缩文件

./compress.sh &

执行脚本

./clean.sh

由于有9个文件正在压缩,所以还剩10个未压缩的文件

if [ 10 -ne ls /data/work1/ | grep -v 7z$ | wc -l ] then echo ‘should have 10 files’ fi

sleep 20

执行脚本

./clean.sh

还有文件正在压缩,所以还剩5个文件

if [ 5 -ne ls /data/work1/ | grep -v 7z$ | wc -l ] then echo ‘should have 5 files’ fi

  1. <a name="tbE7N"></a>
  2. ## 任务4:写一段脚本每小时执行一次,判断每个目录下的带有时间特征的非压缩文件在最近4个小时的文件是否完整,如果不完整自动发邮件报警。
  3. 例如现在时刻是2020年4月25日15点。那么正常情况下/data/work1/目录下肯定至少应该有<br />/data/work1/readme.20200425_12<br />/data/work1/readme.20200425_13<br />/data/work1/readme.20200425_14<br />如果发现目录下缺少了readme.20200425_13,说明可能应用程序出错了,没有打日志,需要发邮件报警,报警内容为,标题:“文件缺失报警”,内容:“readme.20200425_13不存在”
  4. 1. 添加邮件服务
  5. ```bash
  6. [root@localhost data]# sudo apt-get install heirloom-mailx
  7. # 添加配置文件到 /etc/s-nail.rc 末尾
  8. [root@localhost data]# tail /etc/s-nail.rc
  9. # trap \"rm -f \\\"${TMPDIR}/${NAIL_FILENAME_GENERATED}\\\"\" \
  10. # EXIT INT QUIT PIPE TERM;\
  11. # set +C;\
  12. # cat > \"${TMPDIR}/${NAIL_FILENAME_GENERATED}\";\
  13. # xpdf \"${TMPDIR}/${NAIL_FILENAME_GENERATED}\""
  14. # s-it-mode
  15. set from=15609831969@163.com smtp=smtp.163.com
  16. set smtp-auth-user=15609831969@163.com smtp-auth-password=xxxxxx smtp-auth=login
  1. 编写脚本 ```bash [root@localhost data]# cat check.sh

    !/bin/bash

basepath=/data age=${1-4} start_time=`date -d “-$age hour” “+%Y%m%d%H”`

timearr=() for((i=0;i<age;i++));
do
time_arr[i]=`date -d “-$i hour” “+%Y%m%d
%H”` done

check() { dir_path=$1 for prefix_name in ls -l $dir_path | grep ^- | grep -v 7z$ | awk '{print $9}' | sort -r | awk -F . '{if($2>"'$start_time'"){print $1}}' | uniq do for((i=0;i<age;i++));
do file_name=”$prefix_name.${time_arr[i]}” file_path=”$dir_path/$file_name” if [ ! -e $file_path ] then echo “$file_name 不存在” | mail -s “文件缺失报警” 15609831969@163.com fi done
done }

for file_name in ls -l $base_path | grep ^d | awk '{print $9}' do file_path=”$base_path/$file_name” check $file_path done

  1. 3. 添加定时任务
  2. ```bash
  3. [root@localhost data]# crontab -l
  4. * */1 * * * /bin/bash /check.sh
  5. [root@localhost data]# systemctl restart cron