Shell脚本实战:文件统计与进程监控
一、基础题:统计目录下文件类型及数量
需求
写一个脚本,统计指定目录(如/home/user/docs)下不同类型文件的数量,结果按 “类型:数量” 格式输出。文件类型划分规则:
- 普通文件(含文本、二进制等,用
file标识) - 目录(用
dir标识) - 软链接(用
link标识) - 其他类型(用
other标识)
核心考点
for循环遍历目录内容- 文件类型判断(
-f普通文件、-d目录、-L软链接) - 变量计数与输出格式控制
参考解答
#!/bin/bash
# 检查是否传入目录参数
if [ $# -ne 1 ]; thenecho "用法:$0 <目标目录>"exit 1
fitarget_dir=$1
# 初始化计数变量
file_count=0
dir_count=0
link_count=0
other_count=0# 遍历目录下所有内容(*匹配所有,包括隐藏文件)
for item in "$target_dir"/* "$target_dir"/.[!.]*; do# 跳过不存在的条目(避免*未匹配到文件时的空值)[ -e "$item" ] || continueif [ -f "$item" ]; thenfile_count=$((file_count + 1))elif [ -d "$item" ]; thendir_count=$((dir_count + 1))elif [ -L "$item" ]; thenlink_count=$((link_count + 1))elseother_count=$((other_count + 1))fi
done# 输出结果
echo "file:$file_count"
echo "dir:$dir_count"
echo "link:$link_count"
echo "other:$other_count"
二、进阶题:监控进程并自动重启
需求
写一个脚本,监控指定进程(如nginx)是否在运行。如果进程不存在,自动重启该进程;如果重启后 10 秒内仍未启动,输出 “重启失败” 并退出。
核心考点
- 进程查找(
pgrep命令) - 条件判断(进程存在性、重启后状态)
- 延时操作(
sleep) - 系统命令执行(
systemctl或service)
参考解答
#!/bin/bash
# 检查是否传入进程名参数
if [ $# -ne 1 ]; thenecho "用法:$0 <进程名>"exit 1
fiproc_name=$1# 检查进程是否存在(pgrep返回进程ID,无结果则为空)
check_proc() {pgrep "$proc_name" > /dev/null # 重定向输出,避免干扰
}# 第一次检查进程
if check_proc; thenecho "进程$proc_name正在运行"exit 0
elseecho "进程$proc_name未运行,开始重启"# 重启命令(根据系统调整,如service/nginx restart或systemctl restart nginx)systemctl restart "$proc_name" > /dev/null 2>&1 # 重定向错误输出
fi# 等待10秒后再次检查
sleep 10
if check_proc; thenecho "进程$proc_name重启成功"
elseecho "进程$proc_name重启失败"exit 1
fi
三、综合题:日志分析与异常报警
需求
写一个脚本,分析/var/log/nginx/error.log(Nginx 错误日志),统计过去 24 小时内 “502 Bad Gateway” 错误的次数。如果次数超过 10 次,通过echo输出报警信息(实际场景可替换为邮件 / 短信),并将错误详情(含时间、请求地址)保存到/tmp/502_alarm.log。
核心考点
- 日志时间过滤(
grep结合date生成时间范围) - 文本内容提取(
awk提取关键字段) - 计数与阈值判断
- 结果写入文件
参考解答
#!/bin/bash
log_path="/var/log/nginx/error.log"
alarm_path="/tmp/502_alarm.log"
threshold=10 # 错误次数阈值# 生成过去24小时的时间格式(Nginx错误日志时间格式:[26/Oct/2025:10:30:00 +0800])
# 先获取昨天的日期(格式:DD/Mon/YYYY,如25/Oct/2025)
yesterday=$(date -d "1 day ago" +"%d/%b/%Y")
# 获取今天的日期(格式同上)
today=$(date +"%d/%b/%Y")# 过滤过去24小时的502错误:包含yesterday或today的日期,且含502 Bad Gateway
# 同时提取关键信息:时间、请求地址(假设日志格式中请求地址在"request: "后)
error_detail=$(grep -E "($yesterday|$today).*502 Bad Gateway" "$log_path" | \awk -F'[][]' '{time=$2} /request: /{req=$0; sub(/.*request: /,"",req); sub(/,.*$/,"",req)} {print "时间:"time" | 请求地址:"req}')# 统计错误次数
error_count=$(echo "$error_detail" | wc -l)# 判断是否超过阈值
if [ "$error_count" -gt "$threshold" ]; then# 输出报警信息echo "【报警】Nginx 502错误次数超标!"echo "过去24小时错误次数:$error_count(阈值:$threshold)"echo "错误详情已保存至:$alarm_path"# 将详情写入报警文件(覆盖旧文件)echo "$error_detail" > "$alarm_path"
elseecho "过去24小时Nginx 502错误次数:$error_count(未超标)"
fi