shell脚本案例三十 (带详解) (中)

目录

案例十一:查看网卡实时流量

1.问题:

2.分析:

3.流程图:

4.实现:

5.实现解析:

6.结果验证:

案例十二:备份mariadb数据库单循环

1.问题:

2.分析:

3.流程图:

4.实现:

5.实现解析:

6.结果验证:

案例十三:批量修改文件名

1.问题:

2.分析:

3.流程图:

4.实现:

5.实现解析:

6.结果验证:

案例十四:找出某个进程并将其杀掉

1.问题:

2.分析:

3.流程图:

4.实现:

5.实现解析:

6.结果验证:

案例十五:自动创建用户账号

1.问题:

2.分析:

3.流程图:

4.实现:

5.实现解析:

6.结果验证:

案例十六:判断用户输入的是否为IP地址

1.问题:

2.分析:

3.流程图:

4.实现:

5.实现解析:

6.结果验证:

案例十七:提示用户输入年份后判断该年是否为闰年

1.问题:

2.分析:

3.流程图:

4.实现:

5.实现解析:

6.结果验证:

案例十八:自动清理日志文件

1.问题:

2.分析:

3.流程图:

4.实现:

5.实现解析:

6.结果验证:

案例十九:点名器

1.问题:

2.分析:

3.流程图:

4.实现:

5.实现解析:

6.结果验证:

案例二十:监控多台服务器磁盘利用率

1.问题:

2.分析:

3.流程图:

4.实现:

5.实现解析:

6.结果验证:


案例十一:查看网卡实时流量

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输出服务器信息

6.结果验证:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值