Shell脚本实战:从面试题到自动化运维高手

张开发
2026/4/10 23:38:58 15 分钟阅读

分享文章

Shell脚本实战:从面试题到自动化运维高手
1. Shell脚本入门从面试题到实战思维转换很多工程师在面试时能完美解答Shell脚本的理论问题但面对实际运维场景却无从下手。这种脱节现象非常普遍——我们记住了grep的用法却不知道如何用它分析10GB的日志文件我们熟悉for循环语法却不会用它批量处理服务器上的配置文件。我在阿里云做系统架构师时曾用3行Shell脚本替代了一个20分钟的日常操作# 找出所有Java进程并优雅重启 pgrep -f java.*-Dapp | while read pid; do kill -SIGTERM $pid tail --pid$pid -f /dev/null doneShell脚本真正的价值在于将重复劳动转化为自动化流程。比如这个案例传统方式手动ps aux|grep java查进程ID→记录→逐个kill脚本方式自动获取进程ID→智能终止→等待进程结束2. 面试题实战化改造指南2.1 变量使用进阶面试题常问如何定义变量但实际运维需要的是# 好脚本的变量实践 readonly LOG_DIR/var/log/myapp # 常量用readonly declare -i max_retry3 # 声明整数类型 config_file${HOME}/.appcfg # 使用环境变量特别要注意使用${var}而非$var避免歧义数组变量处理日志文件更高效error_logs($(grep -l ERROR /var/log/*.log)) for log in ${error_logs[]}; do send_alert $log # 自定义告警函数 done2.2 条件判断的防错实践教科书上的if [ $var -eq 1 ]在实际中可能引发灾难。正确的姿势是# 安全写法 if [ ${var:-0} -eq 1 ]; then # 处理逻辑 fi # 文件检测要防竞态条件 if [ -f /tmp/lockfile ] [ ! -O /tmp/lockfile ]; then echo 警告锁文件被其他用户持有 2 exit 1 fi3. 经典运维场景解决方案3.1 智能日志分析系统生产环境日志分析需要多工具协同# 多维度日志分析 analyze_log() { local log_file$1 echo $(date) 分析报告 echo [错误统计] grep -c ERROR $log_file | tee -a report.log echo [TOP5耗时请求] awk /Processing time/{print $NF} $log_file | sort -nr | head -5 echo [资源泄漏检测] awk /Memory usage/{if($4threshold) print} threshold500000 $log_file }配合inotifywait可以实现实时监控inotifywait -m -e modify /var/log/nginx/ | while read path action file; do [ $file access.log ] analyze_log $path$file done3.2 服务健康检查框架完整的服务监控应该包含check_service() { local svc$1 systemctl is-active $svc || { systemctl restart $svc send_alert [$HOSTNAME] $svc 服务已重启 } # 深度健康检测 case $svc in mysql) check_mysql_connection ;; nginx) check_nginx_endpoint ;; esac }4. 生产环境脚本进阶技巧4.1 错误处理艺术初级脚本遇到错误就退出高级脚本会# 错误重试机制 retry() { local cmd$1 max${2:-3} delay${3:-1} for ((i1; imax; i)); do if $cmd; then return 0 else sleep $delay fi done return 1 } # 使用示例 retry curl -sSf http://service/api || { escalate_alert API不可用 }4.2 性能优化策略处理大文件时的黄金法则# 糟糕的写法多次读取文件 grep ERROR big.log errors.txt wc -l errors.txt # 优化的写法单次处理 awk /ERROR/{count; print errors.txt} END{print count} big.log使用xargs并行处理# 并行压缩所有日志 find /var/log -name *.log -print0 | xargs -0 -P4 -I{} gzip {}5. 自动化运维体系构建5.1 配置管理模板用脚本生成标准化配置generate_nginx_conf() { local upstream$1 port${2:-80} cat EOF server { listen $port; location / { proxy_pass http://$upstream; proxy_connect_timeout 3s; } } EOF } # 批量生成 generate_nginx_conf backend1 /etc/nginx/conf.d/backend1.conf5.2 安全审计方案自动化安全检查脚本框架audit_system() { check_ssh_config check_sudoers check_file_permissions /etc/passwd 644 } check_file_permissions() { local file$1 expected$2 actual$(stat -c %a $file) [ $actual -eq $expected ] || { send_security_alert $file 权限异常: $actual return 1 } }6. 调试与维护之道6.1 智能调试技巧使用bash -x太基础试试这些# 函数级调试 debug() { echo [DEBUG] ${FUNCNAME[1]}(): $* 2 } process_data() { debug 开始处理 $# 个文件 # ... } # 输出示例 # [DEBUG] process_data(): 开始处理 3 个文件6.2 版本控制集成给脚本添加自检功能#!/bin/bash # Version: 1.2.3 # Changelog: # - 新增重试机制 # - 修复权限问题 show_version() { sed -n 2,5p $0 } case $1 in --version) show_version; exit 0 ;; esac7. 从脚本到工具链的进化7.1 构建自己的CLI工具将常用脚本转化为命令#!/usr/bin/env bash # 文件: /usr/local/bin/sysinfo show_cpu() { lscpu | grep Model name } show_mem() { free -h } case $1 in cpu) show_cpu ;; mem) show_mem ;; *) echo Usage: ${0##*/} [cpu|mem] ;; esac7.2 与CI/CD管道集成在Jenkins Pipeline中使用pipeline { agent any stages { stage(Deploy) { steps { sh #!/bin/bash deploy() { rsync -avz target/ userprod:/opt/app ssh userprod systemctl restart app } deploy } } } }记住优秀的Shell脚本不是写出来的而是在解决实际问题中不断迭代出来的。每次遇到重复操作时先思考这个能否用30行以内的脚本自动化 坚持这个习惯半年后你会发现自己已经建立起一套高效的运维工具链。

更多文章