1. Shell脚本实战经验总结
作为一个常年与Linux服务器打交道的运维工程师,shell脚本是我每天必用的工具。从简单的日志分析到复杂的自动化部署,shell脚本总能以最轻量的方式解决问题。今天我想分享这些年积累的实战经验,这些技巧在官方文档中往往找不到,但能显著提升脚本的健壮性和开发效率。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Shell脚本基础规范
2.1 脚本开头的标准配置
每个shell脚本都应该以shebang开头,我强烈推荐使用#!/usr/bin/env bash而不是直接的#!/bin/bash。这样可以保证脚本在不同系统环境下都能找到合适的解释器。紧随其后应该设置以下参数:
bash复制#!/usr/bin/env bash
set -euo pipefail
set -e:命令执行失败时立即退出set -u:遇到未定义变量时报错set -o pipefail:管道中任意命令失败则整个管道失败
2.2 变量命名的黄金法则
变量命名看似简单,但良好的命名习惯能让脚本可读性大幅提升:
- 常量使用全大写加下划线:
MAX_RETRY=5 - 局部变量使用小写加下划线:
local file_path="/tmp/log" - 避免使用
_开头的变量名(系统保留) - 数组变量加复数后缀:
files=(...)
特别注意:在赋值等号两边不能有空格,这是shell的语法要求,但很多新手容易犯错。
3. 高效字符串处理技巧
3.1 参数扩展的妙用
Shell内置的字符串处理能力经常被低估,其实完全可以替代简单的sed/awk操作:
bash复制filename="app.log.2023-08-01.gz"
# 去除后缀
echo ${filename%.*} # app.log.2023-08-01
# 仅保留后缀
echo ${filename##*.} # gz
# 替换字符串
echo ${filename/./_} # app_log.2023-08-01.gz
3.2 避免临时文件的字符串拼接
多行字符串处理时,很多人会先写入临时文件,其实可以用here-document:
bash复制generate_config() {
cat <<EOF
server {
listen ${PORT:-8080};
root ${WEB_ROOT};
}
EOF
}
4. 错误处理进阶实践
4.1 自定义退出码规范
除了0和1,我们可以定义更丰富的退出码体系:
bash复制readonly ERR_INVALID_INPUT=10
readonly ERR_FILE_NOT_FOUND=11
readonly ERR_PERMISSION_DENIED=12
if [ ! -f "$config_file" ]; then
echo "Config file missing" >&2
exit $ERR_FILE_NOT_FOUND
fi
4.2 优雅的错误捕获
使用trap可以在脚本退出时执行清理工作:
bash复制cleanup() {
rm -rf "$TMP_DIR"
echo "清理临时文件" >&2
}
trap cleanup EXIT ERR INT TERM
5. 性能优化关键点
5.1 减少子进程创建
每行一个命令的写法会产生大量子进程,应该合并操作:
bash复制# 低效写法
grep "ERROR" logfile | awk '{print $2}' | sort | uniq -c
# 高效写法
awk '/ERROR/{print $2}' logfile | sort -u
5.2 选择合适的外部命令
有些命令有更高效的替代品:
| 传统命令 | 高效替代 | 优势 |
|---|---|---|
| grep | ack | 自动递归搜索 |
| find | fd | 执行速度快 |
| cat | bat | 带语法高亮 |
6. 调试技巧大全
6.1 调试模式开关
通过DEBUG环境变量控制调试信息:
bash复制if [ "${DEBUG:-0}" -eq 1 ]; then
set -x
fi
运行时只需:DEBUG=1 ./script.sh
6.2 彩色日志输出
使用ANSI颜色代码提升日志可读性:
bash复制log_error() {
echo -e "\033[31m[ERROR] $*\033[0m" >&2
}
log_info() {
echo -e "\033[32m[INFO] $*\033[0m"
}
7. 实战案例解析
7.1 日志分析脚本优化
原始版本:
bash复制cat access.log | grep "404" | awk '{print $7}' | sort | uniq -c
优化后的版本:
bash复制awk '$9=="404"{count[$7]++} END{for(url in count) print count[url], url}' access.log | sort -nr
优化点:
- 减少管道数量
- 使用数组替代sort+uniq
- 直接按数字逆序排序
7.2 安全的文件遍历
常见的不安全写法:
bash复制for file in $(ls *.log); do
# 可能遇到文件名包含空格的问题
done
正确写法:
bash复制while IFS= read -r -d '' file; do
# 安全处理每个文件
done < <(find . -name '*.log' -print0)
8. 跨平台兼容性处理
8.1 识别操作系统类型
使用uname判断系统:
bash复制case "$(uname -s)" in
Linux*) machine=Linux;;
Darwin*) machine=Mac;;
CYGWIN*) machine=Cygwin;;
MINGW*) machine=MinGw;;
*) machine="UNKNOWN"
esac
8.2 处理不同版本的命令选项
比如date命令在不同系统的表现:
bash复制if [[ "$machine" == "Mac" ]]; then
timestamp=$(date -j -f "%Y-%m-%d" "2023-08-01" "+%s")
else
timestamp=$(date -d "2023-08-01" "+%s")
fi
9. 代码组织最佳实践
9.1 模块化脚本结构
将大脚本拆分为多个小函数:
bash复制main() {
parse_args "$@"
validate_input
process_data
generate_report
}
parse_args() {
# 参数解析逻辑
}
# 其他函数定义...
main "$@"
9.2 使用source加载库文件
创建公共函数库:
bash复制# lib/utils.sh
log_info() {
# 通用日志函数
}
# 主脚本中
source "$(dirname "$0")/lib/utils.sh"
10. 安全编码注意事项
10.1 防止路径遍历攻击
处理用户输入路径时:
bash复制user_input="../../../etc/passwd"
# 不安全
cat "$user_input"
# 安全做法
real_path=$(realpath -- "$user_input")
if [[ "$real_path" != /safe/directory/* ]]; then
echo "非法路径" >&2
exit 1
fi
10.2 密码处理原则
绝对不要在脚本中硬编码密码!应该:
- 使用环境变量
- 从加密的配置文件中读取
- 运行时通过交互式输入
bash复制read -s -p "Enter password: " password
echo
11. 性能监控与调优
11.1 测量命令执行时间
使用time内置命令:
bash复制time {
# 需要测量的代码块
find / -name "*.conf" 2>/dev/null
}
11.2 分析脚本瓶颈
通过set -x和PS4进行详细跟踪:
bash复制PS4='+ $EPOCHREALTIME $(basename ${BASH_SOURCE}):${LINENO} ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
set -x
# 被跟踪的代码
set +x
12. 现代Shell特性应用
12.1 关联数组的使用
Bash 4.0+支持关联数组:
bash复制declare -A error_counts
error_counts["404"]=0
error_counts["500"]=0
while read -r line; do
status=$(get_http_status "$line")
((error_counts["$status"]++))
done < access.log
12.2 进程替换技巧
比较两个命令输出的差异:
bash复制diff <(sort file1) <(sort file2)
13. 实用代码片段集锦
13.1 进度条显示
简单的进度指示器:
bash复制for i in {1..100}; do
printf "\rProgress: [%-100s] %d%%" $(printf '#%.0s' $(seq 1 $i)) $i
sleep 0.1
done
echo
13.2 表格数据输出
格式化显示表格数据:
bash复制printf "%-20s %-10s %-10s\n" "Filename" "Size" "Modified"
printf "%-20s %-10s %-10s\n" "--------" "----" "--------"
find . -maxdepth 1 -type f | while read -r file; do
printf "%-20s %-10s %-10s\n" \
"$(basename "$file")" \
$(du -h "$file" | cut -f1) \
$(date -r "$file" "+%F")
done
14. 版本控制与协作
14.1 脚本头部的元信息
建议每个脚本都包含标准头部:
bash复制#!/usr/bin/env bash
# 脚本名称: deploy.sh
# 作者: Your Name
# 版本: 1.0.0
# 修改日期: 2023-08-01
# 描述: 用于部署应用的自动化脚本
# 使用方式: ./deploy.sh -e prod
14.2 变更日志规范
在脚本内维护简单的变更记录:
bash复制# ChangeLog:
# 2023-07-15 - v1.0.0 - 初始版本
# 2023-07-20 - v1.1.0 - 增加回滚功能
# 2023-08-01 - v1.2.0 - 支持多环境部署
15. 持续集成与测试
15.1 简单的单元测试框架
为关键函数编写测试:
bash复制test_add() {
result=$(add 2 3)
if [ "$result" -eq 5 ]; then
echo "test_add: PASS"
else
echo "test_add: FAIL"
fi
}
add() {
echo $(($1 + $2))
}
# 运行测试
test_add
15.2 ShellCheck静态检查
建议在提交前运行ShellCheck:
bash复制# 安装
apt-get install shellcheck
# 使用
shellcheck script.sh
16. 资源管理与清理
16.1 临时文件管理
使用mktemp创建安全临时文件:
bash复制temp_file=$(mktemp /tmp/script.XXXXXX)
trap 'rm -f "$temp_file"' EXIT
# 使用临时文件
echo "临时数据" > "$temp_file"
16.2 文件描述符管理
避免文件描述符泄漏:
bash复制exec 3< input.txt
while read -u 3 line; do
process_line "$line"
done
exec 3>&-
17. 信号处理进阶
17.1 优雅停止长时间任务
处理SIGTERM信号:
bash复制stop_requested=false
trap 'stop_requested=true' TERM INT
while ! $stop_requested && [ $count -lt 100 ]; do
process_data
((count++))
done
17.2 超时控制
使用timeout命令或内置实现:
bash复制timeout 10s long_running_command || echo "命令超时"
18. 交互式脚本增强
18.1 菜单选择界面
简单的文本菜单:
bash复制show_menu() {
echo "1) 选项一"
echo "2) 选项二"
echo "3) 退出"
read -p "请选择: " choice
case $choice in
1) option_one;;
2) option_two;;
3) exit 0;;
*) echo "无效选择";;
esac
}
18.2 输入验证
安全的数字输入处理:
bash复制read -p "输入数字(1-100): " num
while [[ ! "$num" =~ ^[0-9]+$ ]] || [ "$num" -lt 1 ] || [ "$num" -gt 100 ]; do
read -p "请输入1-100之间的数字: " num
done
19. 系统信息采集
19.1 硬件信息收集
获取系统关键信息:
bash复制get_system_info() {
echo "CPU: $(grep -m1 'model name' /proc/cpuinfo | cut -d: -f2 | sed 's/^ *//')"
echo "Memory: $(free -h | awk '/Mem/{print $2}')"
echo "Disk: $(df -h / | awk 'NR==2{print $4}') available"
}
19.2 性能监控
简单的资源监控:
bash复制monitor_resource() {
while true; do
clear
echo "$(date) 系统负载: $(uptime)"
echo "内存使用: $(free -m | awk '/Mem/{print $3"/"$2 "MB"}')"
sleep 2
done
}
20. 网络操作技巧
20.1 检查网络连通性
可靠的连接测试:
bash复制check_connectivity() {
if curl -sSf --retry 3 --connect-timeout 5 https://example.com >/dev/null; then
echo "网络连接正常"
else
echo "网络连接失败"
return 1
fi
}
20.2 简单的HTTP服务
快速启动临时web服务器:
bash复制start_http_server() {
local port=${1:-8000}
python3 -m http.server "$port" 2>/dev/null &
echo "服务已启动: http://localhost:$port"
}
21. 数据处理与转换
21.1 CSV文件处理
使用awk处理CSV:
bash复制process_csv() {
awk -F, 'NR==1 {split($0,headers); next} {
for(i=1;i<=NF;i++) {
printf "%s=%s ", headers[i], $i
}
print ""
}' data.csv
}
21.2 JSON处理
使用jq工具:
bash复制# 提取JSON字段
get_json_value() {
local json="$1"
local field="$2"
echo "$json" | jq -r ".$field"
}
22. 并发控制模式
22.1 简单的并行处理
使用后台任务:
bash复制for file in *.log; do
process_file "$file" &
((count++))
if (( count % 4 == 0 )); then
wait
fi
done
wait
22.2 使用GNU parallel
更强大的并行工具:
bash复制find . -name '*.log' | parallel -j 4 process_file
23. 日志记录最佳实践
23.1 结构化日志
便于分析的日志格式:
bash复制log() {
local level=$1
shift
printf "[%s] [%s] [%s] %s\n" \
"$(date '+%Y-%m-%d %H:%M:%S')" \
"$level" \
"${SCRIPT_NAME:-$(basename "$0")}" \
"$*" >> "${LOG_FILE:-/var/log/script.log}"
}
23.2 日志轮转
防止日志文件过大:
bash复制rotate_log() {
local log_file=$1
local max_size=${2:-1048576} # 默认1MB
if [ -f "$log_file" ] && [ $(stat -c%s "$log_file") -gt $max_size ]; then
mv "$log_file" "${log_file}.$(date +%Y%m%d%H%M%S)"
gzip "${log_file}.$(date +%Y%m%d%H%M%S)"
fi
}
24. 跨脚本通信
24.1 使用命名管道
实现脚本间通信:
bash复制# 接收端
mkfifo /tmp/script_pipe
while read -r msg; do
echo "收到: $msg"
done < /tmp/script_pipe
# 发送端
echo "消息内容" > /tmp/script_pipe
24.2 信号量控制
简单的进程同步:
bash复制# 等待锁释放
while [ -f /tmp/script.lock ]; do
sleep 1
done
# 获取锁
touch /tmp/script.lock
# 临界区代码
rm -f /tmp/script.lock
25. 实用工具函数库
25.1 日期时间处理
常用日期操作:
bash复制# 获取昨天日期
yesterday() {
date -d "yesterday" "+%Y-%m-%d"
}
# 计算日期差
date_diff() {
local d1=$(date -d "$1" +%s)
local d2=$(date -d "$2" +%s)
echo $(( (d1 - d2) / 86400 ))
}
25.2 数学计算
浮点数运算:
bash复制# 使用bc进行浮点计算
calc() {
echo "$@" | bc -l
}
# 示例
calc "3.14 * 5.67"
26. 环境管理技巧
26.1 环境隔离
使用干净的shell环境:
bash复制run_in_clean_env() {
env -i PATH="$PATH" "$@"
}
26.2 环境变量管理
安全的环境变量处理:
bash复制load_env() {
set -a
[ -f "$1" ] && . "$1"
set +a
}
27. 安全编码进阶
27.1 输入消毒
防止命令注入:
bash复制safe_eval() {
local input=$1
# 只允许字母数字和特定符号
if [[ "$input" =~ ^[a-zA-Z0-9=+/_.,-]*$ ]]; then
eval "$input"
else
echo "非法输入"
return 1
fi
}
27.2 密码生成
安全的随机密码:
bash复制generate_password() {
local length=${1:-16}
tr -dc 'A-Za-z0-9!@#$%^&*()' < /dev/urandom | head -c "$length"
echo
}
28. 国际化支持
28.1 多语言支持
简单的国际化实现:
bash复制set_language() {
case "$1" in
zh)
MSG_GREETING="你好"
MSG_ERROR="错误"
;;
en)
MSG_GREETING="Hello"
MSG_ERROR="Error"
;;
*)
MSG_GREETING="Hi"
MSG_ERROR="Error"
;;
esac
}
28.2 字符编码转换
处理不同编码:
bash复制convert_encoding() {
local file=$1
local from=$2
local to=${3:-UTF-8}
iconv -f "$from" -t "$to" "$file" > "${file}.converted"
}
29. 脚本打包与分发
29.1 自包含脚本
打包依赖文件:
bash复制create_self_extracting_script() {
cat <<'EOF' > bundle.sh
#!/bin/bash
# 自解压脚本
ARCHIVE_START=$(awk '/^__ARCHIVE_BELOW__/ {print NR + 1; exit 0; }' "$0")
tail -n+$ARCHIVE_START "$0" | tar xz
./main_script.sh
exit 0
__ARCHIVE_BELOW__
EOF
tar czf - script.sh data/ config/ >> bundle.sh
chmod +x bundle.sh
}
29.2 版本检查
确保依赖版本:
bash复制check_version() {
local required=$1
local current=$2
if [ "$(printf '%s\n' "$required" "$current" | sort -V | head -n1)" != "$required" ]; then
echo "需要版本 $required 或更高,当前是 $current"
exit 1
fi
}
30. 性能关键代码优化
30.1 避免频繁文件操作
使用内存替代临时文件:
bash复制# 低效
grep "pattern" file > temp
process temp
# 高效
grep "pattern" file | process_pipeline
30.2 使用内置字符串操作
替代外部命令:
bash复制# 低效
len=$(echo "$str" | wc -c)
# 高效
len=${#str}
31. 系统管理实用脚本
31.1 服务监控脚本
检查服务状态:
bash复制check_service() {
local service=$1
if systemctl is-active --quiet "$service"; then
echo "$service 正在运行"
else
echo "$service 已停止"
return 1
fi
}
31.2 磁盘空间监控
预警磁盘使用:
bash复制check_disk_space() {
local threshold=${1:-90}
df -h | awk -v threshold="$threshold" '
NR>1 && $5+0 > threshold {
printf "警告: %s 使用率 %s\n", $1, $5
}'
}
32. 用户输入处理
32.1 交互式确认
安全的确认提示:
bash复制confirm() {
local prompt="$1 [y/N] "
local response
read -rp "$prompt" response
case "$response" in
[yY][eE][sS]|[yY])
return 0
;;
*)
return 1
;;
esac
}
32.2 菜单选择增强
带选项描述的菜单:
bash复制show_menu() {
local options=("1: 部署生产环境" "2: 部署测试环境" "3: 退出")
select opt in "${options[@]}"; do
case $opt in
*生产环境*) deploy prod; break ;;
*测试环境*) deploy test; break ;;
*退出*) exit 0 ;;
*) echo "无效选项" ;;
esac
done
}
33. 正则表达式实战
33.1 邮箱验证
严格的邮箱正则:
bash复制validate_email() {
local email=$1
local regex="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
[[ "$email" =~ $regex ]] && return 0 || return 1
}
33.2 URL提取
从文本提取URL:
bash复制extract_urls() {
grep -oP '(https?|ftp)://[^\s/$.?#].[^\s]*' "$1"
}
34. 文件处理进阶
34.1 大文件处理
高效处理大文件:
bash复制process_large_file() {
while IFS= read -r line; do
# 逐行处理
process_line "$line"
done < "$1"
}
34.2 二进制文件操作
处理二进制数据:
bash复制read_binary() {
local file=$1
local offset=$2
local length=$3
dd if="$file" bs=1 skip="$offset" count="$length" 2>/dev/null | hexdump -v -e '/1 "%02X"'
}
35. 系统信息深度采集
35.1 硬件详细信息
全面的硬件报告:
bash复制hardware_report() {
echo "===== CPU信息 ====="
lscpu
echo
echo "===== 内存信息 ====="
free -h
echo
echo "===== 磁盘信息 ====="
lsblk
}
35.2 网络配置检查
网络接口详情:
bash复制network_info() {
ip -br addr show
echo
ip route
echo
cat /etc/resolv.conf
}
36. 脚本性能分析
36.1 函数执行时间统计
测量函数耗时:
bash复制time_function() {
local func=$1
shift
local start=$(date +%s.%N)
"$func" "$@"
local end=$(date +%s.%N)
echo "执行时间: $(echo "$end - $start" | bc) 秒"
}
36.2 内存使用监控
跟踪脚本内存:
bash复制monitor_memory() {
while true; do
ps -o pid,rss,cmd -C "$(basename "$0")"
sleep 1
done
}
37. 高级文本处理
37.1 多文件内容合并
保持行号关联:
bash复制merge_files() {
paste "$1" "$2" | awk -F'\t' '{printf "%-40s %s\n", $1, $2}'
}
37.2 列数据统计
计算列统计信息:
bash复制column_stats() {
awk '{sum+=$1; sumsq+=$1^2} END{
printf "平均值: %.2f\n", sum/NR;
printf "标准差: %.2f\n", sqrt(sumsq/NR - (sum/NR)^2)
}' "$1"
}
38. 进程管理技巧
38.1 查找并杀死进程
安全的进程终止:
bash复制kill_process() {
local name=$1
local signal=${2:-TERM}
pids=$(pgrep -f "$name")
if [ -n "$pids" ]; then
kill -"$signal" $pids
echo "已发送$signal信号给进程: $pids"
else
echo "未找到匹配进程"
fi
}
38.2 进程树查看
显示进程层次:
bash复制show_process_tree() {
ps axf -o pid,user,cmd
}
39. 系统定时任务
39.1 安全的crontab编辑
避免并发编辑冲突:
bash复制edit_crontab() {
local tempfile=$(mktemp)
crontab -l > "$tempfile"
${EDITOR:-vi} "$tempfile"
crontab "$tempfile"
rm -f "$tempfile"
}
39.2 定时任务验证
检查cron环境:
bash复制test_cron_env() {
echo "PATH: $PATH"
echo "当前用户: $(whoami)"
echo "工作目录: $(pwd)"
echo "时间: $(date)"
}
40. 脚本可移植性
40.1 兼容不同shell
检测当前shell:
bash复制detect_shell() {
case "$SHELL" in
*/bash*) echo "Bash" ;;
*/zsh*) echo "Zsh" ;;
*/ksh*) echo "Ksh" ;;
*) echo "其他: $SHELL" ;;
esac
}
40.2 路径标准化
处理不同路径格式:
bash复制normalize_path() {
local path=$1
if [ -d "$path" ]; then
cd "$path" && pwd
else
local dir=$(dirname "$path")
local base=$(basename "$path")
echo "$(cd "$dir" && pwd)/$base"
fi
}
41. 加密与安全
41.1 文件校验和
验证文件完整性:
bash复制file_checksum() {
local file=$1
local algo=${2:-sha256sum}
$algo "$file" | awk '{print $1}'
}
41.2 简单加密解密
使用openssl:
bash复制encrypt_file() {
local file=$1
openssl enc -aes-256-cbc -salt -in "$file" -out "${file}.enc"
}
decrypt_file() {
local file=$1
openssl enc -d -aes-256-cbc -in "$file" -out "${file%.enc}"
}
42. 脚本文档化
42.1 自动生成帮助
从注释提取帮助:
bash复制show_help() {
grep -E '^# ' "$0" | sed 's/^# //'
}
42.2 Markdown文档生成
脚本转文档:
bash复制generate_docs() {
echo "# $(basename "$0") 文档"
echo
grep -E '^## |^### |^# [^!]' "$0" | while read -r line; do
if [[ "$line" =~ ^##\ ]]; then
echo "##${line:2}"
elif [[ "$line" =~ ^###\ ]]; then
echo "###${line:3}"
else
echo "${line:2}"
fi
done
}
43. 测试驱动开发
43.1 简单的测试框架
实现基本断言:
bash复制assert_equal() {
if [ "$1" != "$2" ]; then
echo "断言失败: '$1' != '$2'"
return 1
fi
}
test_example() {
assert_equal "$(add 2 3)" "5" || return 1
echo "测试通过"
}
43.2 覆盖率统计
跟踪代码执行:
bash复制trace_coverage() {
set -x
# 被测代码
set +x
}
44. 脚本安装器
44.1 自安装脚本
自动部署到PATH:
bash复制self_install() {
local target="/usr/local/bin/$(basename "$0")"
if [ "$(id -u)" -ne 0 ]; then
echo "需要root权限"
return 1
fi
cp "$0" "$target"
chmod +x "$target"
echo "已安装到 $target"
}
44.2 依赖检查
确保依赖可用:
bash复制check_dependencies() {
local missing=()
for cmd in "$@"; do
if ! command -v "$cmd" >/dev/null; then
missing+=("$cmd")
fi
done
if [ ${#missing[@]} -gt 0 ]; then
echo "缺少依赖: ${missing[*]}"
return 1
fi
}
45. 高级调试技术
45.1 跟踪变量修改
调试变量变化:
bash复制trace_variable() {
local var=$1
eval "echo \"$var=\$$var\" >&2"
}
# 使用
trap 'trace_variable important_var' DEBUG
45.2 函数调用跟踪
显示调用栈:
bash复制set_trace() {
export PS4='+${BASH_SOURCE}:${LINENO}:${FUNCNAME[0]}: '
set -x
}
46. 系统配置管理
46.1 配置模板生成
动态生成配置文件:
bash复制generate_config_from_template() {
local template=$1
local output=$2
shift 2
envsubst "$@" < "$template" > "$output"
}
46.2 配置差异检查
比较配置变更:
bash复制check_config_diff() {
local old=$1
local new=$2
diff -u "$old" "$new" | grep -E '^\+[^+]|^\-[^-]'
}
47. 批量操作优化
47.1 并行文件处理
高效批量处理:
bash复制batch_process_files() {
local dir=$1
local workers=${2:-4}
find "$dir" -type f | xargs -P "$workers" -I {} process_file {}
}
47.2 任务队列实现
简单的任务队列:
bash复制run_task_queue() {
local task_file=$1
while read -r task; do
eval "$task"
done < "$task_file"
}
48. 系统日志分析
48.1 错误日志监控
实时错误检测:
bash复制monitor_errors() {
tail -F /var/log/syslog | grep --line-buffered -i error
}
48.2 日志时间统计
分析日志时间分布:
bash复制analyze_log_times() {
awk '/^[A-Z][a-z]{2} [0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/ {
split($3, time, ":");
hour = time[1];
counts[hour]++;
}
END {
for (h in counts) {
printf "%2s时: %4d\n", h, counts[h];
}
}' "$1" | sort -n
}
49. 跨平台脚本技巧
49.1 处理路径差异
Windows/Linux兼容:
bash复制normalize_path() {
local path=$1
if [[ "$OSTYPE" == "msys" ]]; then
cygpath -w "$path"
else
realpath "$path"
fi
}
49.2 命令别名处理
统一命令差异:
bash复制case "$OSTYPE" in
linux*)
alias md5sum='md5sum'
;;
darwin*)
alias md5sum='md5'
;;
esac
50. 脚本工程化实践
50.1 模块化架构
可复用的脚本结构:
bash复制# 主脚本
source "$(dirname "$0")/lib/utils.sh"
source "$(dirname "$0")/lib/config.sh"
main() {
load_config
process_data
generate_output
}
main "$@"
50.2 版本兼容检查
确保环境符合要求:
bash复制check_prerequisites() {
# Bash版本检查
if [ "${BASH_VERSINFO[0]}" -lt 4 ]; then
echo "需要Bash 4.0或更高版本"
exit 1
fi
# 工具检查
local required_tools=(awk sed curl)
for tool in "${required
