Shell案例(30)
案例一:备份文件
1.问题:
(1).用户输入为空
(2).用户输入错误
(3).怎么备份文件
2.分析:
(1).用户输入为空返回输入
(2).用户输入错误退出脚本
(3)使用rsync命令同步文件
3.流程图:
4.实现:
1) #!/bin/bash
2) while :
3) do
4) read -p "请输入你要备份的文件所在的目录:" SOURCE_DIR
5) if [ -n $SOURCE_DIR ]; then
6) if [ ! -d $SOURCE_DIR ]; then
7) echo "目录不存在"
8) exit 1
9) else
10) break
11) fi
12) else
13) continue
14) fi
15) done
16) #获取当前日期
17) DATE=$(date +%Y-%m-%d)
18) #备份路径
19) BACKUP_DIR="/etc/qzj"
20) BACKUP_TARGET="$BACKUP_DIR/$DATE"
21)
22) if [ ! -d $BACKUP_TARGET ]; then
23) mkdir -p $BACKUP_TARGET
24) fi
25)
26) #使用rsync同步文件
27) rsync -avz --delete "$SOURCE_DIR/" "$BACKUP_TARGET" > /dev/null 2>&1
28)
29) if [ $? -eq 0 ]; then
30) echo "备份文件完成,备份文件在$BACKUP_TARGET下"
31) else
32) echo "备份失败"
33) exit 1
34) fi
5.实现解析:
(1).while循环用户输入输入为空返回
(2).输入错误提示目录不存在
(3).使用rsync命令同步文件
(4).检测备份路径是否存在
6.结果验证
案例二:输入网卡的名字,来输出网卡的IP
1.问题:
(1).网卡名输入错误或输入为空怎么办。
(2).网卡名输入正确,是否有这个网卡?
(3).输入的网卡有多个ip时应怎样?
2.分析:
(1).把本机的所有网卡名列出来,来引导用户输入。
(2).在输入网卡名之后直接检测是否有这个网卡。
(3).设计一个函数,把网卡名作为参数,函数返回网卡的IP。
(4).在获取某个网卡IP时,考虑网卡有多个IP地址(或者为空IP的网卡)。
3.流程图:
4.实现:
35) #!/bin/bash
36) #临时文件用于存储原始接口信息
37) i=ip.txt
38) #临时文件用于存储过滤后的接口信息
39) p=ip_back.txt
40) #获取并存储所有接口名称到临时文件
41) echo "接口有:"
42) ip a | awk '/: /{print $2}'
43) ip a | awk '/: /{print $2}' > $i
44) checkip() {
45) #清晰地提示用户输入网卡名
46) read -p "请输入您要查询的网卡名:" A
47) if [ -n "$A" ]; then
48) #删除包含指定网卡名的行并保存到新文件
49) sed "s/\<$A\>//g" $i > $p
50) e=$(wc $i | awk '{print $3}')
51) d=$(wc $p | awk '{print $3}')
52) if [ $e -gt $d ]; then
53) #获取并输出指定网卡的IP地址
54) ip a show dev $A | egrep "inet [0-9]" | awk -F '[ /]+' '{print $3}'
55) return 0
56) else
57) echo "网卡名字错误。"
58) return 1
59) fi
60) else
61) echo "网卡名不能为空。"
62) return 1
63) fi
64) }
65)
66) while true; do
67) if ! checkip; then
68) continue
69) fi
70) break
71) done
5.实现解析:
(1).egrep、sed、awk反复运行命令,来分析执行结果。
(2).将网卡名保存为临时文件。
(3).while死循环。当输入错误或者为空时,继续输入。
(4).while循环continue、break逻辑判断参数。
(5).函数调用。
6.结果验证:
案例三:监控远程的一台机器的存活状态,发现宕机发一封邮件给自己
1.问题:
(1).ping远程机器
(2).发送邮件给自己
(3).mailx服务是否存在
2.分析:
(1).先进行ping通
(2).满足条件后分别返回不同结果
(3).检查mailx服务是否已经安装
3.流程图:
4.实现:
72) #!/bin/bash
73) if [ -n "$1" ]; then
74) ping -c1 -w1 "$1" >/dev/null 2>&1
75) if [ $? -eq 0 ]; then
76) echo "This computer is up"
77) else
78) MAILX_PACKAGE=$(rpm -qa | grep mailx)
79) if [ -z $MAILX_PACKAGE ]; then
80) echo "正在安装mailx服务"
81) yum -y install mailx --nogpgcheck > /dev/null
82) echo "mailx服务安装完成"
83) else
84) echo "mailx服务已存在,无需安装"
85) fi
86) message="This computer with IP address $1 is down"
87) mail -s "warning" root <<< "$message"
88) echo "邮件发送完成
89) 可以使用tail -18 /var/spool/mail/root命令来查看邮件"
90) fi
91) else
92) echo "请在文件后添加IP地址"
93) fi
5.实现解析:
(1).先进行ping主机操作
(2).判断上述条件是否满足
(3).满足返回节点开启
(4).不满足给自己发送邮件告知节点关闭
6.结果验证:
案例四:查看节点是否开启web服务 (80端口)
1.问题:
(1).机器是否开启80端口
(2).端口是被那个服务所占用
(3).是否安装了net-tools
2.分析:
(1).命令netstat查看端口
(2).匹配出服务名称
3.流程图:
4.实现:
94) #!/bin/bash
95) NETSTAT_PACKAGE=$(rpm -qa | grep net-tools)
96) if [ -z $NETSTAT_PACKAGE ]; then
97) echo "正在安装net-tools服务"
98) yum -y install net-tools --nogpgcheck > /dev/null
99) echo "net-tools服务安装完成"
100) else
101) echo "net-tools服务已存在无需安装"
102) fi
103) a=`netstat -ntpl | grep 80`
104) if [ -n "$a" ]; then
105) echo "web server is open"
106) netstat -ntpl | grep 80 | awk -F '/' '{print $NF}'
107) else
108) echo "web server is close"
109) fi
5.实现解析:
(1).查看80端口是否存在
(2).存在,打印结果,并匹配出服务名称
(3).不存在,打印结果
6.结果验证:
案例五:检查特定软件包是否安装
1.问题:
(1).是否添加了参数?
(2).软件包是否安装?
(3)是否安装未安装的软件?
2.分析:
(1).$@提取所有的位置的变量的值
(2).进行判断是否安装
3.流程图:
4.实现:
110) #!/bin/bash
111) if [ $# -eq 0 ]; then
112) echo "你需要制定一个软件包名称作为脚本参数"
113) echo "用法:$0 软件包名"
114) exit 1
115) fi
116) for package in "$@"; do
117) rpm_status=$(rpm -qa ${package} 2>/dev/null)
118) if [ -n "$rpm_status" ]; then
119) echo -e "${package}\033[32;1m 已经安装(版本:${rpm_status##*-\(}\033[0m"
120) else
121) echo -e "${package}\033[34;1m 未安装\033[0m"
122) read -p "是否需要安装${package} (y/n):" A
123) if [ "$A" = y ]; then
124) echo "正在安装${package}"
125) yum -y install ${package} --nogpgcheck > /dev/null
126) echo "${package}安装完成"
127) else
128) exit 1
129) fi
130) fi
131) done
5.实现解析:
(1).判断参数的个数是否为0
(2).$@提取所有位置的变量的值
(3).判断是否安装,返回特定的输出结果
(4).检测出未安装,询问用户是否安装
6.结果验证:
案例六:统计linux进程相关数量信息
1.问题:
(1).查看linux进程
(2).将正在运行、待机、停止等进程数总和列出
2.分析:
(1).将进程id进行循环,依次查看进程状态
(2).进程状态进行叠加,显示进程总数
3.流程图:
4.实现:
132) #!/bin/bash
133) declare -A process_states
134) total_processes=0
135) for pid in /proc/[1-9]*; do
136) ((total_processes++))
137) state=$(awk '{print $3}' "$pid/stat")
138) ((process_states[$state]++))
139) done
140) echo "系统进程如下:"
141) echo "总进程数量为:$total_processes"
142) for state in R S T Z; do
143) count=${process_states[$state]:-0}
144) case $state in
145) R)
146) echo "Running 进程数为: $count"
147) ;;
148) S)
149) echo "Sleep 进程数为: $count"
150) ;;
151) T)
152) echo "Stoped 进程数为: $count"
153) ;;
154) Z)
155) echo "Zombie 进程数为: $count"
156) ;;
157) esac
158) done
5.实现解析:
(1).使用for循环进程一次操作
(2).使用case进行进程状态判断
(3).打印出进程状态数对应总和
6.结果验证:
案例七:查看用户信息
1.问题:
(1).查看有关于用户的一切信息
(2).用户名是否输入为空
(3).用户名是否正确,如果用户名正确又是否有这个用户
2.分析:
(1).找到用户信息
(2).查看对于用户
3.流程图:
4.实现:
159) #!/bin/bash
160) echo "按 Ctrl+C 退出脚本。"
161) while true; do
162) read -p "请输入用户名:" username
163) if [ -z "$username" ]; then
164) echo "用户名不能为空。"
165) else
166) user_info=$(grep "^$username:" /etc/passwd)
167) if [ -n "$user_info" ]; then
168) echo "用户信息:$user_info"
169) # 提取并显示用户的主目录
170) home_dir=$(echo $user_info | awk -F ':' '{print $6}')
171) echo "主目录:$home_dir"
172) break
173) else
174) echo "用户不存在。"
175) fi
176) fi
177) done
5.实现解析:
(1).判断是否输入用户名
(2).判断用户是否存在
(3).存在输出信息
(4).不存在提示信息
6.结果验证:
案例八:监控CPU、内存、磁盘使用情况
1.问题:
(1).获取目前占用资源
2.分析:
(1).利用vmstat命令
(2).显示目前时间
3.流程图:
4.实现:
178) #!/bin/bash
179) DATE=$(date +%F" "%H:%M)
180) #检查vmstat命令是否存在
181) if ! which vmstat > /dev/null 2>&1; then
182) echo "vmstat命令不存在. 请安装procps."
183) exit 1
184) fi
185) #定义阈值变量,可根据实际情况调整
186) cpu_threshold=50
187) mem_threshold=1024 #单位:MB
188) disk_threshold=80
189) #CPU监控
190) cpu_us=$(vmstat | awk 'NR==3 {print $13}')
191) cpu_sy=$(vmstat | awk 'NR==3 {print $14}')
192) cpu_idle=$(vmstat | awk 'NR==3 {print $15}')
193) cpu_use=$((cpu_us + cpu_sy))
194) if [ $cpu_use -ge $cpu_threshold ]; then
195) echo "日期: $DATE, 问题: CPU利用率为 $cpu_use%."
196) fi
197) #内存监控
198) mem_total=$(free -m | awk '/Mem/ {print $2}')
199) mem_used=$(free -m | awk '/Mem/ {print $3}')
200) mem_free=$((mem_total - mem_used))
201) if [ $mem_free -lt $mem_threshold ]; then
202) echo "日期: $DATE, 问题: 总内存为 $mem_total MB. 已用内存为 $mem_used MB. 可用内存小于 $mem_threshold MB."
203) fi
204) #磁盘监控
205) disk_info=$(df -h | awk -F'[% ]+' 'BEGIN{OFS="="} /^\/dev/ {print $1,$2,$5,$6}')
206) for item in $disk_info
207) do
208) disk_part=$(echo $item | cut -d"=" -f1)
209) disk_total=$(echo $item | cut -d"=" -f2)
210) disk_use=$(echo $item | cut -d"=" -f3)
211) disk_mount=$(echo $item | cut -d"=" -f4)
212) used_percent=$(echo $disk_use | cut -d'%' -f1)
213) if [ $used_percent -gt $disk_threshold ]; then
214) echo "日期: $DATE, 总容量: $disk_total, 问题: 设备 $disk_part 的使用率为 $disk_use (挂载点:$disk_mount)."
215) fi
216) done
5.实现解析:
(1).安装procps服务
(2).分别进行if判断
(3).提示执行结果
6.结果验证:
案例九:配置阿里云本地yum源
1.问题:
(1).怎么配置本地yum源
(2).是否配置重复
2.分析:
(1).通过条件判断来确定是否配置
3.流程图:
4.实现:
217) #!/bin/bash
218) repo_file="/etc/yum.repos.d/CentOS-Base.repo"
219) aliyun_url="https://mirrors.aliyun.com/repo/Centos-7.repo"
220) read -p "是否配置阿里云yum源? (y/输入任意键跳过):" A
221) if [ "$A" = y ]; then
222) if grep -q "mirrors.aliyun.com" $repo_file; then
223) echo "阿里云yum源配置已存在,不进行配置"
224) exit 1
225) else
226) if [ -f $repo_file.backup ];then
227) echo "备份已存在"
228) curl -o $repo_file $aliyun_url
229) if [ $? = 0 ]; then
230) yum clean all
231) yum makecache
232) echo "配置阿里云yum源成功"
233) else
234) echo "配置阿里云yum源失败"
235) exit 1
236) fi
237) else
238) mv $repo_file $repo_file.backup
239) curl -o $repo_file $aliyun_url
240) if [ $? = 0 ]; then
241) yum clean all
242) yum makecache
243) echo "配置阿里云yum源成功"
244) else
245) echo "配置阿里云yum源失败"
246) exit 1
247) fi
248) fi
249) fi
250) fi
5.实现解析:
(1).read命令询问是否配置
(2).通过if条件判断来确定是否已经配置
6.结果验证:
案例十:批量检测网站是否异常并发送邮件
1.问题:
(1).如何获取状态码
(2).怎么把URL表里的网站全部检测一次
2.分析:
(1).使用curl命令来获取状态码
(2).使用while循环来检测
3.流程图:
4.实现:
251) #!/bin/bash
252) URL_LIST="www.baidu.com www.ctnrs.com www.der-matech.net.cn www.der-matech.com.cn www.der-matech.cn www.der-matech.top www.der-matech.org"
253) #最大重试次数
254) MAX_RETRIES=3
255) #连接超时秒数
256) CONNECT_TIMEOUT=3
257) check_url() {
258) #函数接受一个参数,将其赋值给局部变量url,代表要检查的 URL。
259) local url=$1
260) #连接失败的次数
261) local fail_count=0
262) while [[ $fail_count -lt $MAX_RETRIES ]]; do
263) http_code=$(curl -o /dev/null --connect-timeout $CONNECT_TIMEOUT -s -w "%{http_code}" $url)
264) if [[ $http_code -eq 200 ]]; then
265) echo "$url OK"
266) return
267) else
268) echo "$url retry $fail_count"
269) ((fail_count++))
270) fi
271) done
272) echo "Warning: $url Access failure!"
273) subject="$url 网站高危"
274) message="网站$url坏掉,请及时处理"
275) echo $message | mail -s "$subject" [email protected]
276) }
277) for url in $URL_LIST; do
278) check_url $url
279) done
5.实现解析:
(1).while循环来连续获取状态码
(2).if判断检测是否为200
(3).等于200输出ok
(4).不等200发出警告并发送邮件