1. Shell编程入门:从简洁到优雅的实战指南
作为Linux系统管理员最趁手的工具,Shell脚本在日常工作中扮演着不可替代的角色。记得我刚入行时,面对一堆需要重复执行的命令手足无措,直到发现Shell脚本这个"自动化神器"。今天分享的这套实例合集,正是我这些年来积累的精华案例,特别适合已经掌握基础语法但缺乏实战经验的朋友。
与传统的语法教程不同,这套实例采用"问题驱动"的设计思路。每个案例都源自真实的运维场景,从最简单的文件备份到复杂的日志分析,你会看到如何用20行代码解决过去需要手动操作半小时的任务。更重要的是,这些脚本都遵循KISS原则(Keep It Simple and Stupid)——没有炫技式的复杂语法,只有最直接的问题解决思路。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与基础规范
2.1 开发环境配置
工欲善其事,必先利其器。推荐使用VS Code作为主要编辑器,安装ShellCheck插件实时检查语法错误。这个组合在我处理生产环境脚本时帮了大忙——有次差点因为一个遗漏的空格导致整晚的批量处理失败,是ShellCheck的红线提示救了我。
bash复制# 安装基础工具(适用于Debian/Ubuntu)
sudo apt update && sudo apt install -y shellcheck tree
# 验证bash版本(建议4.0+)
bash --version | head -n1
注意:生产环境脚本务必在开头使用
#!/usr/bin/env bash而非直接#!/bin/bash,这能更好地处理不同系统的路径差异。这是我用两次凌晨故障换来的经验。
2.2 脚本规范要点
好的脚本应该像说明书一样易读。这是我的团队强制执行的标准:
- 文件名全小写,用连字符分隔(如
backup-mysql.sh) - 函数使用小驼峰命名法(
calculateSize()) - 全局变量全大写加下划线(
MAX_RETRY=3) - 每个函数前必须有注释说明用途和参数
bash复制#!/usr/bin/env bash
# 用途:MySQL数据库备份脚本
# 作者:YourName
# 修改日期:2023-07-20
CONFIG_FILE="/etc/db.conf"
LOG_DIR="/var/log/backup"
# 加载数据库配置
loadConfig() {
[ ! -f "$CONFIG_FILE" ] && echo "Config missing" && exit 1
source "$CONFIG_FILE"
}
3. 经典实例解析
3.1 文件批量处理模板
这是我最常被问到的场景:如何批量重命名/转换/处理一批文件?下面这个模板已经帮我处理过上万张图片和日志文件:
bash复制#!/usr/bin/env bash
# 批量将JPG转换为WebP格式
INPUT_DIR="$1"
OUTPUT_DIR="${INPUT_DIR}_webp"
[ -z "$INPUT_DIR" ] && echo "Usage: $0 <input_dir>" && exit 1
mkdir -p "$OUTPUT_DIR"
convertToWebp() {
local input_file="$1"
local filename=$(basename "$input_file" .jpg)
cwebp -q 80 "$input_file" -o "${OUTPUT_DIR}/${filename}.webp"
}
export -f convertToWebp
find "$INPUT_DIR" -type f -name "*.jpg" | parallel convertToWebp
关键技巧:
- 使用
parallel命令实现多进程并发(处理速度提升5-8倍) export -f将函数传递到子进程- 变量用
${}明确边界,避免歧义
3.2 系统监控报警脚本
这个脚本曾帮我及时发现三次服务器异常,核心是awk的巧妙运用:
bash复制#!/usr/bin/env bash
# 监控CPU/内存/磁盘并发送报警
THRESHOLD_CPU=80
THRESHOLD_MEM=90
THRESHOLD_DISK=85
checkSystem() {
local cpu_usage=$(top -bn1 | awk '/^%Cpu/{print 100-$8}')
local mem_usage=$(free | awk '/Mem/{printf "%.0f", $3/$2*100}')
local disk_usage=$(df -h / | awk 'NR==2{print $5}' | tr -d '%')
(( $(echo "$cpu_usage > $THRESHOLD_CPU" | bc -l) )) && \
sendAlert "CPU" "$cpu_usage"
[ "$mem_usage" -gt "$THRESHOLD_MEM" ] && \
sendAlert "Memory" "$mem_usage"
[ "$disk_usage" -gt "$THRESHOLD_DISK" ] && \
sendAlert "Disk" "$disk_usage"
}
sendAlert() {
local metric=$1
local value=$2
echo "[$(date)] WARNING: $metric usage ${value}%" >> /var/log/system_monitor.log
# 实际环境中这里可以接入邮件/短信报警
}
4. 高级技巧实战
4.1 参数解析最佳实践
很多新手直接用$1、$2处理参数,这在复杂脚本中会成为维护噩梦。这是我总结的模板:
bash复制#!/usr/bin/env bash
# 支持长选项的参数解析模板
usage() {
cat <<EOF
Usage: $0 [OPTIONS]
-h, --help Show this help
-v, --verbose Enable debug output
-f, --file FILE Target file path
EOF
exit 1
}
parseArgs() {
while [ "$#" -gt 0 ]; do
case "$1" in
-h|--help) usage ;;
-v|--verbose) VERBOSE=1 ;;
-f|--file)
[ -z "$2" ] && echo "File path missing" && usage
TARGET_FILE="$2"
shift
;;
*) echo "Unknown option: $1" && usage ;;
esac
shift
done
}
main() {
parseArgs "$@"
[ -z "$TARGET_FILE" ] && echo "File required" && usage
echo "Processing $TARGET_FILE..."
# 业务逻辑
}
4.2 错误处理机制
没有健全的错误处理是脚本最大的安全隐患。这套机制应该成为你的肌肉记忆:
bash复制#!/usr/bin/env bash
# 错误处理模板
set -euo pipefail # 开启严格模式
trap 'cleanup $? $LINENO' EXIT
cleanup() {
local exit_code=$1
local line_no=$2
if [ "$exit_code" -ne 0 ]; then
echo "[ERROR] Failed at line $line_no: $BASH_COMMAND"
# 发送报警/记录日志
fi
# 清理临时文件等资源
rm -rf "$TMP_DIR"
}
main() {
local TMP_DIR=$(mktemp -d)
# 业务逻辑
processData || {
echo "Data processing failed"
return 1
}
}
关键点:
set -euo pipefail是安全脚本的黄金标准trap确保任何情况下都能执行清理- 使用
||处理可预见的错误
5. 性能优化实战
5.1 避免常见性能陷阱
这个日志分析脚本的优化过程很有代表性:
bash复制# 原始版本(处理100MB日志需要58秒)
analyzeLog() {
while read -r line; do
if [[ "$line" =~ "ERROR" ]]; then
echo "$line" >> errors.log
fi
done < system.log
}
# 优化版本(同样日志仅需3秒)
opt
