5个实战Shell脚本从运维场景反向攻克面试考点在技术面试中Shell脚本能力往往是区分普通候选人与优秀候选人的关键分水岭。但传统的死记硬背方式不仅效率低下更无法应对实际工作中复杂多变的需求。本文将带你通过5个真实运维场景中的脚本案例反向拆解Shell面试中的核心知识点让你在实战中自然掌握那些晦涩的概念。1. 日志分析用管道与文本处理三剑客解决实际问题凌晨3点的告警短信总是让人心惊肉跳——某核心服务的错误日志突然暴涨。这时候一个高效的日志分析脚本就是你的救命稻草。下面这个脚本不仅能快速定位问题还涵盖了面试中最常被问到的管道、grep、awk和sed的使用技巧。#!/bin/bash # 实时监控Nginx错误日志中的500状态码 LOG_PATH/var/log/nginx/error.log TEMP_FILE/tmp/error_analysis_$(date %Y%m%d%H%M%S).tmp tail -f $LOG_PATH | grep --line-buffered 500 | awk { gsub(/\/, , $0) # 移除引号干扰 split($0, parts, ) statusparts[9] uriparts[7] ipparts[1] timestampsubstr($0, index($0, [)1, 20) printf [%s] IP:%-15s URI:%-30s Status:%s\n, timestamp, ip, uri, status } $TEMP_FILE # 每小时生成汇总报告 while true; do sleep 3600 echo 过去一小时错误统计 awk {print $4} $TEMP_FILE | sort | uniq -c | sort -nr $TEMP_FILE # 清空临时文件 done关键知识点拆解tail -f实现实时日志监控grep --line-buffered确保实时输出awk的字段分割与格式化输出管道串联多个命令的处理流程这个脚本在实际运维中可以扩展为添加邮件报警功能当500错误超过阈值时触发结合正则表达式识别更多错误模式输出结构化JSON格式便于其他系统消费2. 服务监控用条件判断和函数构建健壮的监控体系服务突然崩溃却不自知这个服务监控脚本不仅能够自动检测服务状态还会智能尝试恢复涵盖了Shell中函数定义、条件判断、退出状态等高频考点。#!/bin/bash # 多服务状态监控与自动恢复脚本 SERVICES(nginx mysql redis-server) MAX_RETRIES3 ALERT_EMAILadminexample.com check_service() { local service$1 if systemctl is-active --quiet $service; then echo [$(date)] $service 运行正常 return 0 else echo [$(date)] $service 服务异常 return 1 fi } restart_service() { local service$1 local retries0 while [ $retries -lt $MAX_RETRIES ]; do echo 尝试重启 $service (第$((retries1))次)... systemctl restart $service if check_service $service; then echo $service 重启成功 return 0 fi sleep 5 ((retries)) done echo 警告$service 重启失败已达到最大尝试次数 send_alert $service return 1 } send_alert() { local service$1 echo 发送告警邮件... mail -s 紧急$service 服务不可用 $ALERT_EMAIL EOF $service 服务在 $(hostname) 上无法正常启动。 请立即检查 最后一次错误日志 $(journalctl -u $service -n 20 --no-pager) EOF } # 主监控循环 while true; do for service in ${SERVICES[]}; do if ! check_service $service; then restart_service $service fi done sleep 60 # 每分钟检查一次 done面试考点映射函数定义与返回值处理return数组遍历与循环控制条件判断的多种写法if、while系统命令的退出状态检测Here Document实现多行文本输入3. 批量用户管理巧用循环和变量实现自动化操作当需要为新项目团队创建50个开发账号时手动操作不仅耗时还容易出错。这个批量用户管理脚本展示了如何用Shell的循环、变量和文本处理能力自动化这一过程同时关联了用户权限管理等重要概念。#!/bin/bash # 批量创建开发团队账户并设置权限 TEAM_NAMEdev_team_2023 BASE_UID5000 BASE_GID5000 USER_LISTuser_list.txt SSH_KEY_DIR/etc/skel/.ssh AUTHORIZED_KEYS$SSH_KEY_DIR/authorized_keys # 准备SSH密钥目录 mkdir -p $SSH_KEY_DIR chmod 700 $SSH_KEY_DIR touch $AUTHORIZED_KEYS chmod 600 $AUTHORIZED_KEYS # 创建开发组 if ! grep -q ^$TEAM_NAME: /etc/group; then groupadd -g $BASE_GID $TEAM_NAME echo 已创建组: $TEAM_NAME (GID: $BASE_GID) fi # 批量创建用户 while IFS, read -r username fullname department; do if id $username /dev/null; then echo 用户 $username 已存在跳过创建 continue fi # 计算UID/GID CURRENT_UID$((BASE_UID)) # 创建用户 useradd -m -u $CURRENT_UID -g $TEAM_NAME -c $fullname,$department -s /bin/bash $username # 设置初始密码 initial_passwd$(openssl rand -base64 12 | tr -d /) echo $username:$initial_passwd | chpasswd # 记录密码到安全文件 echo $username,$initial_passwd,$fullname /var/log/user_creds_$(date %Y%m%d).log # 配置SSH密钥 USER_HOME$(getent passwd $username | cut -d: -f6) cp -r $SSH_KEY_DIR $USER_HOME/ chown -R $username:$TEAM_NAME $USER_HOME/.ssh echo 已创建用户: $username (UID: $CURRENT_UID) done $USER_LIST # 设置目录权限 mkdir -p /shared/$TEAM_NAME chown -R :$TEAM_NAME /shared/$TEAM_NAME chmod 2775 /shared/$TEAM_NAME # 设置SGID位保持组权限 echo 批量用户创建完成。密码日志保存在/var/log/user_creds_$(date %Y%m%d).log关联面试重点while read循环处理文件内容用户和组管理的系统命令useradd,groupadd权限位设置特别是SGID的特殊作用密码安全处理与随机生成批量操作中的错误处理与跳过机制4. 自动备份用tar和日期变量构建可靠备份方案数据丢失是运维人员的噩梦。这个智能备份脚本不仅实现了增量备份、过期清理等企业级功能还巧妙运用了Shell中的日期处理、文件测试和信号捕获等高级特性。#!/bin/bash # 智能备份脚本增量备份过期清理 BACKUP_DIR/backup DATA_DIRS(/var/www /etc /home) RETENTION_DAYS30 LOG_FILE/var/log/backup_$(date %Y%m).log COMPRESS_LEVEL6 # 创建备份目录 mkdir -p $BACKUP_DIR/full $BACKUP_DIR/incremental # 信号处理备份被中断时记录日志 trap echo [$(date)] 备份被用户中断 $LOG_FILE; exit 1 INT TERM log() { echo [$(date)] $1 $LOG_FILE } full_backup() { local backup_file$BACKUP_DIR/full/full_$(date %Y%m%d).tar.gz log 开始完整备份... tar -czvf $backup_file --exclude*.tmp --exclude*.log --excludecache/* \ -g $BACKUP_DIR/full.snar ${DATA_DIRS[]} $LOG_FILE 21 if [ $? -eq 0 ]; then log 完整备份成功: $backup_file return 0 else log 完整备份失败! return 1 fi } incremental_backup() { local last_full$(ls -t $BACKUP_DIR/full/*.tar.gz | head -1) [ -z $last_full ] { log 未找到完整备份无法执行增量备份; return 1; } local incr_file$BACKUP_DIR/incremental/incr_$(date %Y%m%d_%H%M).tar.gz log 开始增量备份基于: $last_full tar -czvf $incr_file --exclude*.tmp --exclude*.log --excludecache/* \ -g $BACKUP_DIR/full.snar ${DATA_DIRS[]} $LOG_FILE 21 if [ $? -eq 0 ]; then log 增量备份成功: $incr_file return 0 else log 增量备份失败! return 1 fi } clean_old_backups() { log 清理超过${RETENTION_DAYS}天的备份... find $BACKUP_DIR/full -name *.tar.gz -mtime $RETENTION_DAYS -delete find $BACKUP_DIR/incremental -name *.tar.gz -mtime $RETENTION_DAYS -delete log 旧备份清理完成 } # 根据日期决定执行完整备份还是增量备份 day_of_week$(date %u) # 1-7 (1是周一) day_of_month$(date %d) # 01-31 if [ $day_of_week -eq 1 ] || [ $day_of_month -eq 1 ]; then full_backup || exit 1 else incremental_backup || exit 1 fi clean_old_backups核心技术要点tar的增量备份机制-g选项日期变量的灵活运用date %formatfind命令实现过期文件清理trap信号捕获处理意外中断备份策略设计每周/每月完整备份日志记录与错误处理机制5. 系统安全检查用正则表达式和文件测试构建安全扫描工具安全无小事。这个系统安全检查脚本能够自动化完成多项常见安全检查涉及Shell中正则表达式、文件测试操作符、进程管理等高级特性这些都是Shell面试中的难点所在。#!/bin/bash # 自动化系统安全检查脚本 REPORT_FILE/var/log/security_audit_$(date %Y%m%d).report HIGH_RISK0 WARNINGS0 check_pass() { echo -e \n 密码策略检查 # 检查密码过期策略 local pass_max_days$(grep -P ^PASS_MAX_DAYS /etc/login.defs | awk {print $2}) [ $pass_max_days -gt 90 ] { echo [高危] 密码最长使用天数过长: ${pass_max_days}天 (建议≤90天) ((HIGH_RISK)) } || echo [通过] 密码最长使用天数: ${pass_max_days}天 # 检查空密码账户 local empty_pass$(awk -F: ($2 ) {print $1} /etc/shadow) [ -n $empty_pass ] { echo [高危] 存在空密码账户: $empty_pass ((HIGH_RISK)) } || echo [通过] 未发现空密码账户 } check_ssh() { echo -e \n SSH配置检查 # 检查Root登录是否允许 grep -qP ^PermitRootLogin\sno /etc/ssh/sshd_config || { echo [高危] SSH允许Root登录 (建议禁用) ((HIGH_RISK)) } # 检查密码认证是否禁用 grep -qP ^PasswordAuthentication\sno /etc/ssh/sshd_config || { echo [警告] SSH允许密码认证 (建议使用密钥认证) ((WARNINGS)) } } check_suid() { echo -e \n 危险SUID文件检查 # 查找非常规SUID文件 local suid_files$(find / -perm -4000 -type f ! -path /proc/* 2/dev/null) local dangerous_suid(/usr/bin/passwd /usr/bin/sudo /usr/bin/chsh /usr/bin/mount) for file in $suid_files; do if ! printf %s\n ${dangerous_suid[]} | grep -q ^$file$; then echo [高危] 发现非常规SUID文件: $file ((HIGH_RISK)) fi done [ $HIGH_RISK -eq 0 ] echo [通过] 未发现非常规SUID文件 } check_cron() { echo -e \n 定时任务检查 # 检查系统级定时任务 local cron_dirs(/etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly /etc/cron.d) for dir in ${cron_dirs[]}; do [ -d $dir ] { local suspicious$(find $dir -type f \( -perm -ow -o ! -user root \) 2/dev/null) [ -n $suspicious ] { echo [高危] 发现可疑定时任务文件: $suspicious ((HIGH_RISK)) } } done # 检查用户级定时任务 local user_crons$(cut -d: -f1 /etc/passwd | xargs -I{} crontab -l -u {} 21 | grep -v no crontab) local suspicious_user_crons$(echo $user_crons | grep -Pv #|^$|^[a-zA-Z0-9/_.-] (cd [a-zA-Z0-9/_.-] )?[a-zA-Z0-9/_.-]) [ -n $suspicious_user_crons ] { echo [高危] 发现可疑用户定时任务: echo $suspicious_user_crons ((HIGH_RISK)) } || echo [通过] 未发现可疑定时任务 } generate_report() { echo -e \n 安全检查报告 $(date) $REPORT_FILE echo 高危问题: $HIGH_RISK $REPORT_FILE echo 警告问题: $WARNINGS $REPORT_FILE if [ $HIGH_RISK -gt 0 ]; then echo -e \n[行动建议] 发现高危安全问题请立即处理 $REPORT_FILE elif [ $WARNINGS -gt 0 ]; then echo -e \n[行动建议] 发现潜在安全问题建议尽快检查。 $REPORT_FILE else echo -e \n[检查结果] 系统安全状态良好 $REPORT_FILE fi echo -e \n报告已保存到: $REPORT_FILE } # 执行所有检查 check_pass check_ssh check_suid check_cron generate_reportShell高级特性应用正则表达式在配置文件检查中的应用grep -P文件权限测试操作符-perm进程和用户权限检查数组用于白名单管理风险分级与报告生成这五个脚本不仅解决了实际运维中的痛点问题更系统性地覆盖了Shell脚本面试中的核心考点。通过这种从实际问题反推知识点的学习方式你会发现那些抽象的概念突然变得具体而有意义。记住优秀的Shell程序员不是背出来的而是在解决一个又一个真实问题中成长起来的。