目录
案例十一:查看网卡实时流量
1.问题:
(1).是否提供了接口参数
(2).提供的接口参数是否存在
2.分析:
(1).检查$1是否为空
(2).查看提供的接口是否存在于/proc/net/dev中
3.流程图:
4.实现:
280) #!/bin/bash
281) #检查是否提供了网络接口参数
282) if [ -z "$1" ]; then
283) echo "请提供要监控的网络接口名称作为参数。"
284) exit 1
285) fi
286) if grep -q "$1" /proc/net/dev; then
287) #定义第一个参数
288) NIC="$1"
289) #显示流入和流出
290) echo -e "In ------- Out"
291) while true; do
292) #获取旧的流入和流出字节数
293) OLD_IN=$(awk '$0~"'$NIC'"{print $2}' /proc/net/dev)
294) OLD_OUT=$(awk '$0~"'$NIC'"{print $10}' /proc/net/dev)
295) sleep 1
296) #获取新的流入和流出字节数
297) NEW_IN=$(awk '$0~"'$NIC'"{print $2}' /proc/net/dev)
298) NEW_OUT=$(awk '$0~"'$NIC'"{print $10}' /proc/net/dev)
299) #计算流量速度并输出
300) IN=$(printf "%.1f%s" "$((($NEW_IN-$OLD_IN)/1024))" "KB/s")
301) OUT=$(printf "%.1f%s" "$((($NEW_OUT-$OLD_OUT)/1024))" "KB/s")
302) echo "$IN $OUT"
303) sleep 1
304) done
305) else
306) echo "网络接口名称不存在"
307) exit 1
308) fi
5.实现解析:
(1).if判断来确定是否输入和存在
(2).while死循环持续输出
6.结果验证:
案例十二:备份mariadb数据库单循环
1.问题:
(1).备份目录是否存在
(2).怎么备份数据库
2.分析:
(1).判断备份目录是否存在
(2).使用mysqldump命令来进行备份
3.流程图:
4.实现:
309) #!/bin/bash
310) #设置日期格式
311) DATE=$(date +%F_%H-%M-%S)
312) #设置备份目录
313) BACKUP_DIR="/data/db_backup"
314) #设置 MySQL 用户和密码(从环境变量中读取,提高安全性)
315) USER=root
316) PASS=123456
317) #创建备份目录(如果不存在)
318) if [ ! -d "$BACKUP_DIR" ]; then
319) mkdir -p "$BACKUP_DIR"
320) fi
321) #获取数据库列表并过滤系统数据库
322) DB_LIST=$(mysql -u"$USER" -p"$PASS" -s -e "show databases" | egrep -v "information_schema|mysql|performance_schema|test")
323) #备份每个数据库
324) for DB in $DB_LIST; do
325) BACKUP_NAME="$BACKUP_DIR/${DB}_${DATE}.sql"
326) if ! mysqldump -u"$USER" -p"$PASS" -B "$DB" > "$BACKUP_NAME" > /dev/null 2>&1; then
327) echo "[$(date +'%Y-%m-%d %H:%M:%S')] $BACKUP_NAME 备份失败" | tee -a /var/log/db_backup.log
328) else
329) echo "[$(date +'%Y-%m-%d %H:%M:%S')] $BACKUP_NAME 备份成功" | tee -a /var/log/db_backup.log
330) fi
331) done
5.实现解析:
(1).if条件判断是否有备份目录
(2).for循环备份数据库
(3).输出提示并写入日志
6.结果验证:
案例十三:批量修改文件名
1.问题:
(1).是否输入了目录参数
(2).目录和文件是否存在
(3).批量修改.txt为bak.txt
(4).把所有.bak文件打包压缩成123.tar.gz
(5).批量还原文件的名字
2.分析:
(1).使用if条件语句
(2).将所有的文件名先写到临时文件中
(3).对临时文件进行改名操作
3.流程图:
4.实现:
332) #!/bin/bash
333) #检查是否传入了目录参数
334) if [ -z "$1" ]; then
335) echo "请提供一个目录作为参数。"
336) exit 1
337) fi
338) #检查目录是否存在
339) if [ ! -d "$1" ]; then
340) echo "目录不存在"
341) exit 1
342) fi
343) #文件名储存文件夹
344) if [ ! -f txtname ]; then
345) touch txtname
346) fi
347) if [ ! -f bakname ]; then
348) touch bakname
349) fi
350) #---------------
351) cd $1
352) find *.txt > txtname
353) for i in `cat txtname`
354) do
355) mv $i $i.bak
356) done
357) tar -zcvf 123.tar.gz *.bak
358) find *.bak > bakname
359) for n in `cat bakname`
360) do
361) mv $n ${n%.*}
362) done
5.实现解析:
(1).进入目标目录
(2).找到所有文件,将所有文件名写到临时文件
(3).针对临时文件进行改名操作
(4).压缩所有目标文件名的文件
(5).同样操作针对于改名后的文件在进行改名,改为原来的文件名
6.结果验证:
案例十四:找出某个进程并将其杀掉
1.问题:
(1).怎么找到这个进程
(2).这个进程是否存在
(3).一个进程有多个id
2.分析:
(1).使用grep、awk命令来打印出进程id
(2).使用if判断
(3).for循环将id逐个杀死
3.流程图:
4.实现:
363) #!/bin/bash
364)
365) NAME=$1
366)
367) #获取进程 ID,并确保不为空
368) PID=$(ps -aux | grep "$NAME" | grep -v "$0" | grep -v "grep" | awk '{print $2}')
369) if [ -z "$PID" ]; then
370) echo "未找到名为 $NAME 的进程。"
371) exit 1
372) fi
373)
374) #循环终止进程,并进行错误处理
375) for id in $PID; do
376) if kill -9 $id >/dev/null 2>&1; then
377) echo "成功终止进程 $id。"
378) else
379) echo "无法终止进程 $id。"
380) fi
381) done
5.实现解析:
(1).grep命令排除自身和排除脚本来查找,awk打印id
(2).for循环将多个id逐个杀死
6.结果验证:
案例十五:自动创建用户账号
1.问题:
(1).是否有这个用户
(2).怎么同时创建多个用户
2.分析:
(1).使用条件判断语句
(2).利用循环来同时创建多个用户
3.流程图:
4.实现:
382) #!/bin/bash
383) #检查用户是否存在,不存在则创建
384) createuser(){
385) for i in $(seq 1 20); do
386) if id "user${i}" > /dev/null 2>&1; then
387) echo "user${i} 已存在!"
388) else
389) if useradd "user${i}"; then
390) echo "user${i}" | passwd --stdin user${i} > /dev/null 2>&1
391) if [ $? = 0 ]; then
392) echo "成功创建用户user${i}"
393) else
394) echo "创建用户user${i}成功,但设置密码失败"
395) fi
396) else
397) echo "创建用户user${i}失败"
398) fi
399) fi
400) done
401) }
402) createuser
5.实现解析:
(1).调用函数
(2).for循环创建20个用户
(3).if判断语句输出结果
6.结果验证:
案例十六:判断用户输入的是否为IP地址
1.问题:
(1).IP地址格式是否正确
(2).输入的是否为IP地址
2.分析:
(1).输出提示,引导输入ip
(2).awk命令判断每个位置是否正确
3.流程图:
4.实现:
403) #!/bin/bash
404) #定义函数check_ip用于检查输入的IP地址是否合法
405) check_ip() {
406) local IP=$1
407) #将 IP 地址按照 "." 分隔成四个字段,并使用 awk 判断每个字段的取值范围是否合法(0-255)
408) VALID_CHECK=$(echo $IP | awk -F"." '{if($1<=255&&$2<=255&&$3<=255&&$4<=255) print "yes"; else print "no"}')
409) #使用正则表达式验证 IP 地址的格式,必须为 1-3 位数字 + “.” + 1-3 位数字 + “.” + 1-3 位数字 + “.” + 1-3 位数字.
410) if echo $IP | grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" > /dev/null; then
411) if [[ "$VALID_CHECK" == "yes" ]]; then
412) echo "$IP 可用."
413) return 0
414) else
415) echo "$IP 不可用!"
416) return 1
417) fi
418) else
419) echo "格式错误!"
420) return 1
421) fi
422) }
423)
424) while true; do
425) #提示用户输入 IP 地址
426) read -p "请输入IP: " ip
427) #调用函数 check_ip,传入用户输入的 IP 地址作为参数进行检查
428) #如果函数返回值为 0,表示 IP 地址合法,跳出循环
429) #如果函数返回值为 1,表示 IP 地址不合法,继续循环
430) check_ip $ip
431) done
5.实现解析:
(1).调用函数
(2).grep、awk命令确定IP地址格式是否正确
(3).while循环输入ip地址
6.结果验证:
案例十七:提示用户输入年份后判断该年是否为闰年
1.问题:
(1).输入年份是否为空
(2).输入的不为空但不是数字
2.分析:
(1).提示用户输入年份
(2).考虑用户输入年份是否为空或者是否为数字
3.流程图:
4.实现:
432) #!/bin/bash
433) while true; do
434) read -p "请输入一个年份:" year
435) #检查输入是否为空
436) if [ -z "$year" ]; then
437) echo "没有输入年份 请重新输入"
438) continue
439) fi
440) #检查输入的是否为数字
441) if ! [[ "$year" =~ ^[0-9]+$ ]]; then
442) echo "您输入的不是有效的数字 请重新输入"
443) continue
444) fi
445) #判断闰年
446) if [ $[year % 4] -eq 0 ] && [ $[year % 100] -ne 0 ] && [ $[year % 400] -eq 0 ]; then
447) echo "$year年是闰年"
448) else
449) echo "$year不是闰年"
450) fi
451) read -p "是否继续判断其他年份? (y/n):" A
452) if ! [[ "$A" = y ]]; then
453) break
454) fi
455) done
5.实现解析:
(1).用户输入为空白时,提示没有输入年份
(2).用户输入为字母时,提示输入不是数字
(3).用户输入是数字时,与四、一百、四百进行计算
6.结果验证:
案例十八:自动清理日志文件
1.问题:
(1).脚本输入错误
(2).如何计算天数
(3).输出单一只有删除
2.分析:
(1).引导用户输入
(2).利用date命令时间戳和bc命令来计算
(3).添加多种输出并整合到一个文件
3.流程图:
4.实现:
456) #!/bin/bash
457) #记录脚本执行过程的日志
458) LOG_CLEAN_LOG_FILE="/var/log/log_clean.log"
459) if ! [[ -f var/log/log_clean.log ]]; then
460) touch /var/log/log_clean.log
461) fi
462) #判断输入是否正确
463) if [ $# -ne 2 ]; then
464) echo "用法:$0 (日志目录) (保留天数)"
465) exit 1
466) fi
467) #从命令行获取要清理的日志文件的目录和保留天数
468) LOG_DIR=$1
469) DAYS_TO_KEEP=$2
470) #获取当前时间的时间戳
471) current_time=$(date +%s)
472) #对日志目录下的所有文件进行处理
473) for file in $(find $LOG_DIR -type f); do
474) #获取文件的创建时间戳
475) file_time=$(stat -c %Y $file)
476) #计算当前时间与文件创建时间的时间差
477) age=$(($current_time - $file_time))
478) #将时间差转换为天数,通过bc命令进行计算
479) age_days=$(bc <<< "scale=2; $age /(60 * 60 * 24)")
480) if [ $? -ne 0 ]; then
481) echo "[$(date +'%Y-%m-%d %H:%M:%S')]将文件$file的时间差转换为天数时出错,请检查bc命令是否可用。" >> $LOG_CLEAN_LOG_FILE
482) continue
483) fi
484) #判断文件存在天数是否大于保留天数
485) if [ $(echo "$age_days > $DAYS_TO_KEEP" | bc) -eq 1 ]; then
486) #在删除文件前记录相关信息到日志文件
487) echo "[$(date +'%Y-%m-%d %H:%M:%S')]正在删除文件:$file,因为该文件已存在$age_days天,超过了保留天数$DAYS_TO_KEEP天。" >> $LOG_CLEAN_LOG_FILE
488) #删除文件
489) rm -f $file
490) echo "[$(date +'%Y-%m-%d %H:%M:%S')]已删除文件:$file" >> $LOG_CLEAN_LOG_FILE
491) else
492) #记录未达到清理条件而保留的文件信息到日志文件
493) echo "[$(date +'%Y-%m-%d %H:%M:%S')] 文件$file未达到清理条件,保留该文件。(已存在$age_days天,保留天数为$DAYS_TO_KEEP天)" >> $LOG_CLEAN_LOG_FILE
494) fi
495) done
5.实现解析:
(1).创建log_clean.log文件来存放相关输出信息,便于查看
(2).输入错后引导用户输入
(3).通过输入的日志路径和保留天数来确定该删什么
6.结果验证:
案例十九:点名器
1.问题:
(1).用户名输出重复
(2).用户输入
2.分析:
(1).定义数组来进行去重
(2).使用配置文件方式来输入
3.流程图:
4.实现:
496) #!/bin/bash
497) #用于存储已经输出过的用户名的数组
498) outputted_users=()
499) #检查user.txt文件是否存在
500) if ! [[ -f user.txt ]]; then
501) touch user.txt
502) fi
503) #提示用户输入需要的用户名
504) read -p "请输入用户名:" USER_NAME
505) echo "$USER_NAME" > user.txt
506) #读取user.txt文件内容并转换为数组
507) user_array=($(cat user.txt))
508) #获取用户名数组的长度
509) line=${#user_array[@]}
510)
511) while :
512) do
513) #随机生成一个尚未输出过的行号
514) while true; do
515) num=$[RANDOM%line+1]
516) user=${user_array[num - 1]}
517) #检查用户名是否在已输出数组中
518) if [[ ! " ${outputted_users[@]} " =~ " ${user} " ]]; then
519) break
520) fi
521) done
522) #输出当前随机选择的用户名
523) echo $user
524) #将当前输出的用户名添加到已输出数组中
525) outputted_users+=($user)
526) #检查是否所有用户名都已输出
527) if [ ${#outputted_users[@]} -eq $line ]; then
528) break
529) fi
530)
531) read -p "按任意键继续(输入q退出):" input
532) if [ "$input" == "q" ]; then
533) break
534) fi
535) done
5.实现解析:
(1).定义两个数组 一个空数组一个带有用户名行数的数组
(2).用read命令将输入的内容赋给变量。输出变量到文件中
(3).将输出的用户名添加到空数组当中也就是已输出数组中
(4).当用户名数组的长度等于已输出数组的长度时结束整个循环
6.结果验证:
案例二十:监控多台服务器磁盘利用率
1.问题:
(1).是否有存储文件
(2).怎么获取ip 用户名 端口号
(3).分析磁盘空间
2.分析:
(1).判断是否有存储文件
(2).awk打印字段
3.流程图:
4.实现:
536) #!/bin/bash
537) #IP 用户名 端口号储存文件
538) HOST_INFO=host.info
539) if [ ! -f $HOST_INFO ]; then
540) touch $HOST_INFO
541) fi
542) #遍历获取的ip
543) for IP in $(awk '/^[^#]/{print $1}' $HOST_INFO); do
544) #获取用户名和端口号
545) USER=$(awk -v ip=$IP 'ip==$1{print $2}' $HOST_INFO)
546) PORT=$(awk -v ip=$IP 'ip==$1{print $3}' $HOST_INFO)
547) #磁盘信息储存文件
548) TMP_FILE=/tmp/disk.tmp
549) if [ ! -f $TMP_FILE ]; then
550) touch $TMP_FILE
551) fi
552) #通过公钥登入获取主机磁盘信息
553) ssh -p $PORT $USER@$IP 'df -h' > $TMP_FILE
554) #分析磁盘占用空间
555) USE_RATE_LIST=$(awk 'BEGIN{OFS="="}/^\/dev/{print $NF,int($5)}' $TMP_FILE)
556) #遍历磁盘列表
557) for USE_RATE in $USE_RATE_LIST; do
558) #取挂载点名称
559) PART_NAME=${USE_RATE%=*}
560) #取磁盘利用率
561) USE_RATE=${USE_RATE#*=}
562) if [ $USE_RATE -ge 80 ]; then
563) echo "Warning: $PART_NAME Partition usage $USE_RATE%!"
564) echo "服务器$IP的磁盘空间占用过高,请及时处理"
565) else
566) echo "服务器$IP的$PART_NAME目录空间良好"
567) fi
568) done
569) done
5.实现解析:
(1).if判断存储文件是否存在
(2).awk命令找出想要的信息
(3).for循环取多台服务器信息
(4).echo输出服务器信息