Linux基础与Shell脚本:运维自动化的第一块基石

说实话,很多刚入行的运维同学,上来就追着Kubernetes、Docker跑。我特别理解,新技术确实吸引人。但我要泼盆冷水——你连Linux基础都没打牢,Shell脚本写不利索,后面搞自动化就是空中楼阁。

我在交易系统运维这行干了快十年,见过太多事故了。有一次,一个同事因为误删了日志文件,导致磁盘空间没释放,最后整个交易链路卡死。为什么?因为他不懂lsof命令,不知道进程还在占用文件句柄。你看,一个基础命令没用好,就能引发生产事故。

所以这一章,咱们把地基夯实。我会把最常用的Linux命令、Vim编辑技巧、Shell脚本核心写法,还有定时任务和日志管理,一次性讲透。

核心观点:交易系统的运维自动化,90%的日常操作都可以用Shell脚本+定时任务搞定。别小看这些基础,它们是你未来构建CI/CD流水线、监控告警系统的底层能力。

2.1 Linux常用命令:生产环境下的生存指南

我习惯把Linux命令分成几类。你不需要背几百个,但下面这些,必须烂熟于心。

2.1.1 文件操作三板斧

  • ls -ltr:按时间排序查看文件。我每次排查问题,第一件事就是跑这个命令,看看最近改了哪些文件。
  • find /path -name "*.log" -mtime -1:查找最近一天修改过的日志文件。这个在定位故障时特别有用。
  • du -sh * | sort -rh:查看当前目录下各文件/文件夹的大小,从大到小排序。磁盘告警时,这命令能帮你快速找到“罪魁祸首”。

我的习惯:我会在~/.bashrc里给这些常用命令设置别名。比如alias ll='ls -ltr'alias dus='du -sh * | sort -rh'。省时间,真的省时间。

2.1.2 进程与资源监控

交易系统对资源敏感,CPU、内存、磁盘IO,哪个出问题都可能引发延迟飙升。

命令 用途 我的实战场景
top -c 查看进程CPU/内存占用 发现某个交易进程CPU跑满,直接定位到PID
iostat -x 1 磁盘IO实时监控 磁盘写延迟超过100ms,果断换SSD
netstat -anp | grep :8080 查看端口监听状态 服务启动失败,检查端口是否被占用
strace -p PID 跟踪系统调用 进程卡死?看它卡在哪个系统调用上

嗯,这里要注意strace。我曾经用它抓到一个诡异问题:一个交易进程每隔30秒就卡顿一次,最后发现是NFS挂载点超时重试。没有strace,这种问题根本无从下手。

2.1.3 文本处理三剑客

grep、awk、sed,这三个命令是Shell脚本的灵魂。我每天至少用它们几十次。

# 从交易日志中提取所有成交记录
grep "成交" trade.log | awk '{print $1, $3, $5}' | sort | uniq -c

# 批量替换配置文件中的IP地址
sed -i 's/192.168.1.100/10.0.0.100/g' config/*.yml

# 统计每个交易品种的成交量
awk '{sum[$2] += $3} END {for (k in sum) print k, sum[k]}' trade_data.txt

避坑指南:我曾经在生产环境上直接用了sed -i,结果替换错了字符串。从那以后,我养成了习惯——先用sed不带-i跑一遍,确认无误再加-i。或者用sed -i.bak保留备份。

2.2 Vim编辑器:运维人员的第二双手

说实话,很多新手觉得Vim难用。我刚开始也这么想。但当你需要在没有图形界面的服务器上,快速修改一个配置文件时,Vim就是唯一的选择。

你不需要学所有Vim技巧。掌握下面这些,日常运维就够用了。

2.2.1 生存模式:20%的命令解决80%的问题

  • i:进入插入模式。按Esc退出。
  • :wq:保存退出。我习惯用:x,效果一样,少按一个键。
  • :q!:不保存强制退出。改错了?别慌,用这个。
  • /keyword:搜索关键词。按n跳到下一个,N跳到上一个。
  • dd:删除当前行。yy:复制当前行。p:粘贴。
  • u:撤销。我按u的频率比任何键都高。

我的小技巧:/etc/vim/vimrc里加上set numberset cursorline。显示行号,高亮当前行。排查日志时,能快速定位到具体行号。

2.2.2 高效编辑三板斧

当你需要批量修改时,别一行一行改。用Vim的替换功能。

# 把文件中所有的"old_ip"替换成"new_ip"
:%s/old_ip/new_ip/g

# 只替换第10到20行
:10,20s/old_ip/new_ip/g

# 替换前确认
:%s/old_ip/new_ip/gc

为什么推荐加c?我曾经一次替换了200个文件,结果发现有个注释里的字符串也被替换了。从那以后,批量替换我必加c,逐个确认。

2.3 Shell脚本基础:从手动到自动的关键一步

Shell脚本,说白了就是把你在命令行里敲的命令,写到一个文件里,然后让它自动执行。交易系统的很多日常操作——比如启动服务、备份数据、清理日志——都可以用脚本自动化。

2.3.1 脚本结构:先想清楚再动手

我写脚本有个习惯:先画流程图,再写代码。别急着敲键盘,想清楚逻辑再动手。

#!/bin/bash
# 交易系统健康检查脚本
# 作者:资深SRE
# 日期:2024-01-01

# 设置变量
LOG_DIR="/var/log/trade"
ALERT_EMAIL="ops@example.com"
THRESHOLD=90

# 检查磁盘使用率
DISK_USAGE=$(df -h /data | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt "$THRESHOLD" ]; then
    echo "磁盘使用率超过${THRESHOLD}%,当前:${DISK_USAGE}%" | mail -s "告警" $ALERT_EMAIL
fi

# 检查交易进程是否存活
if ! pgrep -x "trade_server" > /dev/null; then
    echo "交易进程异常退出,正在重启..."
    /usr/local/bin/start_trade.sh
fi

关键点:脚本开头一定要加#!/bin/bash。变量命名要有意义。每个功能模块用空行隔开。这些习惯,能让你三个月后回看脚本时,还能一眼看懂。

2.3.2 条件判断与循环:脚本的灵魂

没有判断和循环的脚本,就是个命令列表。真正的自动化,需要根据条件做决策,需要批量处理。

# 遍历所有交易日志,找出异常记录
for log_file in /var/log/trade/*.log; do
    if grep -q "ERROR" "$log_file"; then
        echo "发现异常:$log_file"
        # 提取错误信息并发送告警
        grep "ERROR" "$log_file" | mail -s "交易异常" ops@example.com
    fi
done

# 重试机制:最多重试3次
MAX_RETRY=3
RETRY_COUNT=0
until [ $RETRY_COUNT -ge $MAX_RETRY ]; do
    if /usr/local/bin/sync_data.sh; then
        echo "数据同步成功"
        break
    else
        RETRY_COUNT=$((RETRY_COUNT + 1))
        echo "同步失败,第${RETRY_COUNT}次重试..."
        sleep 5
    fi
done

你想想看,如果没有这个重试机制,网络抖动一次,数据同步就断了。交易系统最怕数据不一致,对吧?

2.3.3 函数封装:别重复造轮子

我见过最糟糕的脚本,同样的代码复制粘贴了十几遍。一旦要改,得改十几个地方。用函数封装,一劳永逸。

# 日志函数
log() {
    local level=$1
    local message=$2
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message" >> /var/log/ops_script.log
}

# 发送告警函数
send_alert() {
    local subject=$1
    local body=$2
    echo "$body" | mail -s "$subject" ops@example.com
    log "INFO" "告警已发送:$subject"
}

# 使用示例
log "INFO" "开始执行数据备份"
send_alert "备份完成" "交易数据备份已于$(date)完成"

我的建议:把常用的函数放到一个独立的common.sh文件里。每个脚本开头source common.sh就行。这样所有脚本共享一套函数,维护成本直线下降。

2.4 定时任务:让脚本自动跑起来

脚本写好了,总不能每天手动执行吧?定时任务就是干这个的。交易系统里,定时任务用得特别多:

  • 每天凌晨备份数据库
  • 每小时清理过期日志
  • 每5分钟检查一次服务健康状态
  • 每周生成交易报表

2.4.1 Crontab:最经典的定时任务

Crontab的格式,说白了就是“分时日月周”。我刚开始也记不住,后来发现一个口诀:

# 格式:分 时 日 月 周 命令
# 每天凌晨2点执行备份
0 2 * * * /usr/local/bin/backup.sh

# 每5分钟检查一次服务
*/5 * * * * /usr/local/bin/health_check.sh

# 每周一早上8点生成报表
0 8 * * 1 /usr/local/bin/gen_report.sh

# 每月1号清理日志
0 0 1 * * /usr/local/bin/clean_logs.sh

避坑指南:我曾经在crontab里直接写了一个脚本,结果脚本里的环境变量全都不生效。为什么?因为crontab执行时,不会加载~/.bashrc。解决方案:在脚本开头显式设置环境变量,或者用source /etc/profile加载全局配置。

2.4.2 Systemd Timer:更现代的方案

如果你用的是CentOS 7+或Ubuntu 16+,我建议你试试Systemd Timer。它比Crontab更灵活,支持依赖管理、日志记录、失败重试。

# 创建一个service文件:/etc/systemd/system/backup.service
[Unit]
Description=交易数据备份服务

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=root

# 创建一个timer文件:/etc/systemd/system/backup.timer
[Unit]
Description=每天凌晨2点执行备份

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.target

启用定时器:

systemctl daemon-reload
systemctl enable backup.timer
systemctl start backup.timer

为什么推荐Systemd Timer?因为它有日志。如果脚本执行失败,journalctl -u backup.service能直接看到错误输出。Crontab呢?你得自己重定向日志,麻烦。

2.5 日志管理:运维人员的眼睛

交易系统出了问题,第一件事就是看日志。但日志文件动辄几个GB,怎么快速找到问题?怎么防止日志把磁盘撑爆?

2.5.1 日志轮转:别让日志撑爆磁盘

我见过最惨的事故:一个交易系统跑了半年没清理日志,结果磁盘满了,服务直接挂掉。日志轮转,就是给日志文件设置一个“寿命”。

# /etc/logrotate.d/trade
/var/log/trade/*.log {
    daily                # 每天轮转一次
    rotate 30            # 保留30天的日志
    compress             # 压缩旧日志
    delaycompress        # 延迟一天压缩
    missingok            # 日志不存在不报错
    notifempty           # 空文件不轮转
    copytruncate         # 先复制再清空,不影响进程写日志
    postrotate
        /usr/bin/killall -HUP trade_server  # 通知进程重新打开日志文件
    endscript
}

我的习惯:我会在postrotate里加上sleep 1。为什么?因为有些进程收到HUP信号后,不会立即重新打开文件。等一秒,确保切换完成。

2.5.2 日志分析:从海量数据中快速定位

交易日志里,每一行都包含时间戳、交易ID、操作类型、耗时等关键信息。怎么快速分析?

# 统计最近一小时的错误数
grep "$(date '+%Y-%m-%d %H')" trade.log | grep "ERROR" | wc -l

# 找出耗时超过1秒的交易
awk '{if ($NF > 1000) print $0}' trade.log

# 统计每个交易品种的平均耗时
awk '{sum[$2] += $3; count[$2]++} END {for (k in sum) print k, sum[k]/count[k]}' trade.log

嗯,这里要注意。交易日志的格式一定要统一。我见过最头疼的情况:同一个系统的日志,不同模块的格式不一样。解析起来简直要命。所以,从一开始就定好日志规范,比什么都重要。

2.6 本章知识体系总览

下面这张图,是我梳理的本章核心知识结构。你可以把它当作一个“地图”,随时回来查阅。

Linux基础与Shell脚本知识体系 运维自动化基石 Linux常用命令 Vim编辑器 Shell脚本基础 定时任务与日志管理 文件操作 进程监控 文本处理 生存模式 高效编辑 脚本结构 条件循环 函数封装 Crontab Systemd Timer 日志轮转 核心目标:从手动运维 → 脚本自动化 → 定时执行 交易系统运维的日常操作,90%可被脚本化

这张图把本章内容串起来了。你看,从Linux命令到Vim,再到Shell脚本,最后用定时任务和日志管理收尾。每一步都是下一步的基础。别跳着学,一步一步来。


好了,这一章的内容就到这里。Linux基础打牢了,Shell脚本能写能跑了,定时任务和日志管理也上手了。接下来,你就可以用这些工具,去构建更复杂的自动化体系了。

记住,交易系统运维的核心不是花哨的技术,而是稳定、可靠、可重复。而这些,都从你手下的每一行命令、每一个脚本开始。

专注资料整理