Shell 三剑客与自动化脚本实践
运维的日常工作(看日志、查状态、做巡检)如果全靠手工敲命令,一天什么都干不了。把重复操作沉淀成脚本 + 定时任务,是运维从”救火”走向”自动化”的分水岭。这篇整理三剑客和 Shell 脚本的实战用法。
一、三剑客:grep / sed / awk
grep:过滤文本
1 2 3 4
| grep -n "ERROR" app.log grep -v "^#" nginx.conf egrep -n "ERROR|WARN" app.log grep -A5 "Exception" app.log
|
sed:按行过滤与批量修改
sed 是流编辑器,按行处理、无需打开文件,脚本化修改配置的核心工具。
1 2 3 4
| sed -n '10,20p' nginx.conf sed -i 's/8080/8081/g' nginx.conf sed -i '/^#/d' nginx.conf sed -n '/^server/,/}/p' nginx.conf
|
两个纪律:①-i 前先备份(cp xxx xxx.bak),改配置类文件尤其如此;②替换匹配尽量精确,避免误伤。
awk:取行取列与统计
1 2 3 4
| awk '{print $1, $3}' access.log awk '$9 == 500 {print $1}' access.log awk '{count[$1]++} END{for (k in count) print k, count[k]}' access.log | sort -k2 -rn | head
|
二、Shell 脚本规范
脚本骨架
1 2 3 4 5
| #!/bin/bash
set -e
LOG_DIR="/data/logs"
|
变量与传参
1 2 3 4 5 6 7 8
|
ping -c1 www.baidu.com >/dev/null 2>&1 && echo "通" || echo "不通"
PORT=${PORT:-3306}
[ $# -lt 1 ] && echo "用法: $0 参数1" && exit 1
|
条件与循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| [ $FREE -lt 10 ] && echo "磁盘空间不足" [ -f /etc/nginx/nginx.conf ] && echo "存在" [ -z "$VAR" ] && echo "变量为空"
for ip in 10.0.8.11 10.0.8.12; do ping -c1 -W1 $ip >/dev/null && echo "$ip 通" || echo "$ip 不通"; done while read line; do echo "$line"; done < list.txt
case "$1" in start) systemctl start nginx ;; stop) systemctl stop nginx ;; *) echo "用法: $0 start|stop" ;; esac
|
函数与局部变量
1 2 3
| log_info() { local msg="$1"; echo "[INFO] $(date '+%F %T') $msg"; } check_disk() { local use=$(df -h / | awk 'NR==2{print $5}' | tr -d '%'); [ "$use" -gt 80 ] && echo "根分区使用率 ${use}%"; }
|
三、定时任务:crontab
五段式:分 时 日 月 周 命令。
1 2 3 4 5 6 7 8 9 10
| crontab -e
0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1
*/10 * * * * /opt/scripts/check.sh
0 3 * * 0 /opt/scripts/cleanup.sh
crontab -l crontab -r
|
定时任务三个高频坑:
- 脚本里的环境变量(PATH)是精简的:在 crontab 里直接写
rsync、python3 可能 command not found——脚本开头显式定义或用绝对路径;
- 输出重定向必须写:不写
>> log 2>&1,脚本报错内容会发到系统邮箱(没人看),排障全靠猜;
- 任务没执行先查三件事:
crontab -l 任务在不在、脚本权限(chmod +x)、手动跑一遍有没有报错。
四、一个完整的巡检脚本案例
把”每天的磁盘/内存/负载巡检”沉淀成脚本,配 crontab 每天跑,结果统一写到日志:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #!/bin/bash
LOG="/var/log/ops/daily-check.log" TS=$(date '+%F %T')
echo "===== $TS 巡检开始 =====" >> $LOG
df -h | awk 'NR>1 && $5+0 > 80 {print "磁盘告警: " $0}' >> $LOG
free -h | awk 'NR==2 {print "内存: 总量"$2" 已用"$3" 可用"$7}' >> $LOG
LOAD=$(uptime | awk -F'load average:' '{print $2}' | cut -d, -f1) echo "负载: $LOAD" >> $LOG
|
1
| 0 8 * * * /opt/scripts/daily-check.sh
|
脚本化的收益是复利式的:每次把重复操作写成脚本 + 定时任务,后面所有机器都能复用,也逼着自己把每一步操作想清楚——这正是排查和自动化能力一起提升的过程。