1. Linux操作系统基础概述
Linux作为现代计算领域最重要的开源操作系统之一,已经渗透到从嵌入式设备到超级计算机的各个领域。与Windows等商业操作系统不同,Linux采用模块化设计,其核心是Linus Torvalds于1991年开发的Linux内核。这个内核负责管理硬件资源、进程调度和基础安全机制,而围绕它的各种发行版(如Ubuntu、CentOS、Debian等)则提供了完整的用户环境。
Linux系统的典型目录结构遵循文件系统层次标准(FHS)。根目录(/)下包含/bin(基础命令)、/etc(配置文件)、/home(用户目录)、/usr(用户程序)等关键目录。理解这种结构对系统管理和脚本编写至关重要——比如,系统级脚本通常放在/etc/init.d,而用户自定义脚本更适合放在~/bin或/usr/local/bin。
提示:在Linux中,一切皆文件。硬件设备、进程信息甚至系统参数都以文件形式暴露在/proc和/sys目录下,这种设计哲学使得shell脚本能够通过简单的文件操作完成复杂的系统管理任务。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Shell环境与基础命令实战
Shell是用户与Linux内核交互的接口,常见的Shell包括Bash(Bourne-Again Shell)、Zsh和Fish等。Bash作为大多数Linux发行版的默认Shell,其脚本兼容性最好。通过echo $SHELL可以查看当前使用的Shell,而chsh命令可用于切换默认Shell。
文件操作是Shell编程的基础:
bash复制# 创建并操作文件
touch demo.txt # 创建空文件
echo "内容" > demo.txt # 覆盖写入
echo "追加" >> demo.txt # 追加内容
cp demo.txt backup/ # 复制文件
mv demo.txt newname.txt # 重命名
rm -i *.txt # 交互式删除
进程管理常用命令:
bash复制ps aux | grep nginx # 查看进程
kill -9 PID # 强制终止进程
nice -n 10 command # 调整优先级
nohup command & # 后台运行
网络工具链示例:
bash复制ifconfig/ip addr # 查看IP
ping -c 4 example.com # 网络测试
netstat -tulnp # 端口监听
ssh user@host # 远程登录
scp file user@host:~/ # 安全传输
3. Shell脚本编程核心要素
一个完整的Shell脚本通常以shebang开头,指定解释器路径:
bash复制#!/bin/bash
# 注释:这是一个示例脚本
变量处理需要注意:
bash复制name="value" # 定义变量
echo $name # 使用变量
readonly name # 设为只读
unset name # 删除变量
数组和特殊变量:
bash复制files=(*.txt) # 创建数组
echo ${files[0]} # 访问元素
echo $# $* $? $$ $0 # 参数/状态变量
流程控制结构:
bash复制# 条件判断
if [ -f "/path" ]; then
echo "文件存在"
elif [ -d "/path" ]; then
echo "目录存在"
else
echo "不存在"
fi
# 循环示例
for i in {1..5}; do
echo "迭代 $i"
done
while read line; do
echo "处理: $line"
done < input.txt
4. 高级Shell技巧与实战案例
函数和参数处理:
bash复制process_file() {
local filename=$1 # 局部变量
[[ -f "$filename" ]] || return 1
echo "处理: $(wc -l < "$filename") 行"
return 0
}
process_file "data.txt"
echo "退出状态: $?"
正则表达式应用:
bash复制# 提取日志中的IP地址
grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' access.log
# 批量重命名
for file in *.jpg; do
mv "$file" "${file%.jpg}_$(date +%Y%m%d).jpg"
done
调试技巧:
bash复制#!/bin/bash -x # 启用调试模式
set -euo pipefail # 严格模式:错误退出、未定义变量检测、管道错误
trap 'echo "错误发生在第 $LINENO 行"' ERR
实际案例:自动化备份脚本
bash复制#!/bin/bash
# 定义配置
BACKUP_DIR="/backups"
DB_USER="admin"
DB_PASS="secret"
RETENTION_DAYS=7
# 创建日期标记
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# MySQL数据库备份
mysqldump -u$DB_USER -p$DB_PASS --all-databases | gzip > \
$BACKUP_DIR/db_backup_$TIMESTAMP.sql.gz
# 文件系统备份
tar -czf $BACKUP_DIR/fs_backup_$TIMESTAMP.tar.gz \
--exclude="*.tmp" /var/www /etc/nginx
# 清理旧备份
find $BACKUP_DIR -type f -name "*.gz" -mtime +$RETENTION_DAYS -delete
# 记录日志
logger -t backup "系统备份完成于 $TIMESTAMP"
5. 系统管理与脚本安全
用户权限管理:
bash复制sudo visudo # 安全编辑sudoers
chmod 755 script.sh # 设置权限
chown user:group file # 变更属主
环境变量配置:
bash复制# ~/.bashrc 示例
export PATH="$PATH:/usr/local/bin"
export EDITOR=vim
alias ll='ls -alF'
脚本安全注意事项:
- 总是验证用户输入,防范命令注入:
bash复制# 危险示例
read -p "输入文件名: " filename
rm "$filename" # 可能执行恶意输入如"* /"
# 安全做法
if [[ "$filename" =~ ^[a-zA-Z0-9_-.]+$ ]]; then
[ -f "$filename" ] && rm "$filename"
fi
- 使用密码时避免明文存储:
bash复制# 使用openssl加密敏感信息
encrypted=$(echo "secret" | openssl enc -aes-256-cbc -a -salt)
echo "$encrypted" > config.enc
- 设置脚本执行超时:
bash复制timeout 30s ./long_running.sh || {
echo "脚本执行超时"
killall -9 long_running.sh
}
6. 性能优化与跨平台兼容
提高脚本执行效率:
bash复制# 减少子进程调用(反例)
for i in $(seq 1 100); do
echo $i | wc -c
done
# 优化方案(使用内置功能)
for ((i=1; i<=100; i++)); do
printf "%d" $i | wc -c
done
处理大文件的技巧:
bash复制# 低效方式
while read line; do
process "$line"
done < huge_file.txt
# 高效方案(使用awk等专业工具)
awk '{print length($0)}' huge_file.txt
跨平台兼容性处理:
bash复制#!/bin/bash
# 检测操作系统类型
case "$(uname -s)" in
Linux*) machine=Linux;;
Darwin*) machine=Mac;;
CYGWIN*) machine=Cygwin;;
MINGW*) machine=MinGw;;
*) machine="UNKNOWN"
esac
# 平台特定处理
if [ "$machine" = "Linux" ]; then
alias md5sum='md5 -r' # Mac兼容
fi
7. 现代Shell编程进阶
关联数组(Bash 4.0+):
bash复制declare -A colors=(
[red]="#FF0000"
[green]="#00FF00"
[blue]="#0000FF"
)
echo ${colors[red]} # 输出 #FF0000
进程替换与协程:
bash复制# 比较两个命令输出
diff <(ls /dir1) <(ls /dir2)
# 协程示例
coproc MYPROC {
echo "子进程PID: $BASHPID"
read -r input
echo "收到: $input"
}
echo "消息" >&${MYPROC[1]}
正则表达式高级匹配:
bash复制# 提取URL中的域名
url="https://sub.example.com/path"
if [[ $url =~ ^https?://([^/]+) ]]; then
echo "域名: ${BASH_REMATCH[1]}"
fi
8. 实战:构建系统监控脚本
以下是一个综合性的系统监控脚本示例:
bash复制#!/bin/bash
# 系统监控脚本 v1.2
# 配置阈值
CPU_WARN=80
MEM_WARN=90
DISK_WARN=85
# 获取系统状态
cpu_usage=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')
mem_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
disk_usage=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
# 告警检查
alerts=()
[ $(echo "$cpu_usage > $CPU_WARN" | bc) -eq 1 ] && alerts+=("CPU使用率过高: ${cpu_usage}%")
[ $(echo "$mem_usage > $MEM_WARN" | bc) -eq 1 ] && alerts+=("内存使用率过高: ${mem_usage}%")
[ $disk_usage -gt $DISK_WARN ] && alerts+=("磁盘空间不足: ${disk_usage}%")
# 生成报告
report="系统状态报告 $(date)\n"
report+="----------------------------------\n"
report+="CPU使用率: ${cpu_usage}%\n"
report+="内存使用率: ${mem_usage}%\n"
report+="根分区使用: ${disk_usage}%\n"
if [ ${#alerts[@]} -gt 0 ]; then
report+="\n[!] 告警:\n"
for alert in "${alerts[@]}"; do
report+="- $alert\n"
done
# 发送邮件通知
echo -e "$report" | mail -s "系统告警" admin@example.com
fi
# 记录日志
echo -e "$report" >> /var/log/system_monitor.log
这个脚本展示了如何:
- 使用各种命令组合获取系统指标
- 进行数值比较和阈值判断
- 构建多行报告文本
- 实现简单的告警通知机制
- 记录历史数据供后续分析
9. Shell脚本调试与错误处理
Bash脚本调试技术:
bash复制#!/bin/bash -xv # 启用详细调试
set -e # 遇到错误立即退出
set -u # 使用未定义变量时报错
set -o pipefail # 管道命令失败时整个命令失败
# 自定义调试信息
debug() {
[ "$DEBUG" = "true" ] && echo "[DEBUG] $@" >&2
}
debug "开始处理数据文件"
# 错误处理示例
cleanup() {
echo "清理临时文件..."
rm -f "$TEMP_FILE"
}
trap cleanup EXIT ERR INT TERM
# 使用ERR陷阱记录错误行号
trap 'echo "错误发生在第 $LINENO 行"' ERR
日志记录最佳实践:
bash复制log() {
local level=$1
shift
local message="$@"
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
# 根据日志级别决定是否显示
case "$level" in
ERROR) echo "$message" >&2 ;;
WARN) [ "$VERBOSE" = "true" ] && echo "$message" >&2 ;;
esac
}
log INFO "脚本启动"
log ERROR "配置文件缺失" # 会显示到stderr
10. Shell与其他语言的协作
调用Python处理复杂逻辑:
bash复制#!/bin/bash
# 使用Python进行JSON解析
json_data='{"name":"John", "age":30}'
name=$(python3 -c "import sys,json; print(json.loads(sys.argv[1])['name'])" "$json_data")
echo "姓名: $name"
# 生成复杂数据结构
python_script='
import sys, json
data = {
"users": [{"id": i, "name": f"user_{i}"} for i in range(3)],
"timestamp": "2023-01-01"
}
print(json.dumps(data))
'
config_data=$(python3 -c "$python_script")
echo "$config_data" | jq . # 使用jq工具美化输出
与数据库交互示例:
bash复制# MySQL查询
read -r -d '' SQL <<'EOF'
SELECT user, host FROM mysql.user
WHERE user NOT LIKE 'mysql.%'
ORDER BY user;
EOF
mysql -u root -p"$DB_PASSWORD" -e "$SQL" | while read -r user host; do
echo "用户: $user@$host"
done
# 使用sqlite
sqlite3 test.db "CREATE TABLE IF NOT EXISTS logs (
id INTEGER PRIMARY KEY,
message TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);"
sqlite3 test.db "INSERT INTO logs (message) VALUES ('脚本执行开始');"
11. 自动化运维实战案例
案例1:批量服务器配置检查
bash复制#!/bin/bash
# servers.txt格式: user@host:port
SERVERS_FILE="servers.txt"
OUTPUT_REPORT="server_report_$(date +%Y%m%d).csv"
echo "Hostname,OS,Kernel,CPU,Cores,Memory,Disk" > "$OUTPUT_REPORT"
check_server() {
local server=$1
echo "检查服务器: $server"
ssh -n "$server" "
hostname=\$(hostname)
os=\$(grep PRETTY_NAME /etc/os-release | cut -d'\"' -f2)
kernel=\$(uname -r)
cpu=\$(grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2 | sed 's/^[ \t]*//')
cores=\$(grep -c '^processor' /proc/cpuinfo)
memory=\$(free -h | grep Mem | awk '{print \$2}')
disk=\$(df -h / | awk 'NR==2 {print \$4}')
echo \"\$hostname,\$os,\$kernel,\$cpu,\$cores,\$memory,\$disk\"
" >> "$OUTPUT_REPORT"
}
# 并行执行检查
export -f check_server
parallel -j 10 check_server :::: "$SERVERS_FILE"
echo "检查完成,报告已保存到 $OUTPUT_REPORT"
案例2:日志分析报警系统
bash复制#!/bin/bash
# 实时监控Nginx错误日志
LOG_FILE="/var/log/nginx/error.log"
ALERT_THRESHOLD=10 # 每分钟错误阈值
SLACK_WEBHOOK="https://hooks.slack.com/services/..."
# 使用tail -F实时跟踪日志
tail -n0 -F "$LOG_FILE" | while read line; do
# 统计每分钟500错误数
errors=$(grep -c ' 500 ' <(tail -n1000 "$LOG_FILE" | grep "$(date +'%H:%M')"))
if [ "$errors" -ge "$ALERT_THRESHOLD" ]; then
message="[警报] $(date) - 检测到高频率500错误: $errors 次/分钟"
echo "$message"
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$message\"}" "$SLACK_WEBHOOK"
# 提取最近错误示例
grep ' 500 ' <(tail -n50 "$LOG_FILE") > /tmp/nginx_errors_sample.log
# 可以添加自动重启服务等恢复逻辑
fi
done
12. Shell脚本性能调优
减少子进程调用:
bash复制# 低效方式(每次循环都调用date)
for i in {1..1000}; do
timestamp=$(date +%s)
echo "$timestamp" >> times.txt
done
# 高效方式(使用Bash内置功能)
for i in {1..1000}; do
echo $EPOCHREALTIME >> times.txt
sleep 0.01
done
使用coproc处理大量数据:
bash复制# 传统管道方式(每个处理步骤都是独立进程)
cat bigfile.txt | grep "error" | sed 's/foo/bar/' | sort > output.txt
# 使用coproc减少进程创建
coproc GREP {
grep "error" bigfile.txt
}
coproc SED {
sed 's/foo/bar/' <&${GREP[0]}
}
sort <&${SED[0]} > output.txt
并行处理加速:
bash复制# 串行处理
for file in *.log; do
gzip "$file"
done
# GNU parallel并行处理
parallel -j 8 gzip ::: *.log
# 使用xargs并行
find . -name "*.log" -print0 | xargs -0 -P 4 -n 1 gzip
13. 安全编程实践
安全注意事项:
- 避免使用eval:
bash复制# 危险示例
user_input='rm -rf /'
eval "$user_input"
# 安全替代方案
case "$user_input" in
safe_command) command_to_run ;;
*) echo "无效命令" ;;
esac
- 安全的临时文件创建:
bash复制# 不安全方式
tempfile="/tmp/temp.$$"
echo "数据" > "$tempfile"
# 安全做法
tempfile=$(mktemp /tmp/secure.XXXXXXXXXX)
trap 'rm -f "$tempfile"' EXIT
echo "安全数据" > "$tempfile"
- 密码处理:
bash复制# 不安全:密码在命令行参数可见
mysql -u root -p"plaintext_password"
# 更安全方式
read -s -p "输入密码: " db_password
mysql -u root -p"$db_password" <<< "SHOW DATABASES;"
unset db_password
- 输入验证:
bash复制# 文件名验证
if [[ "$filename" =~ ^[a-zA-Z0-9_.-]+$ ]]; then
[ -f "$filename" ] || { echo "文件不存在"; exit 1; }
else
echo "无效文件名" >&2
exit 1
fi
14. 现代Shell生态工具链
开发辅助工具:
- ShellCheck - 静态分析工具:
bash复制# 安装
sudo apt install shellcheck
# 使用
shellcheck script.sh
- Bash调试器bashdb:
bash复制# 安装
sudo apt install bashdb
# 调试会话
bashdb script.sh
- 高级文本处理工具:
bash复制# jq处理JSON
curl -s api.example.com/data.json | jq '.users[] | select(.age > 30)'
# yq处理YAML
yq e '.services.web.ports' docker-compose.yml
# rg (ripgrep)快速搜索
rg -t sh 'function.*{' ~/scripts/
- 终端多路复用器tmux:
bash复制# 创建会话
tmux new -s dev_session
# 分屏操作
Ctrl+b % # 垂直分割
Ctrl+b " # 水平分割
Ctrl+b → # 切换窗格
# 后台运行
tmux detach
tmux attach -t dev_session
15. Shell脚本项目化实践
项目目录结构示例:
code复制~/projects/
└── system_tools/
├── bin/ # 可执行脚本
│ ├── backup.sh
│ └── monitor.sh
├── lib/ # 公共函数库
│ └── utils.sh
├── etc/ # 配置文件
│ └── backup.conf
├── logs/ # 日志文件
├── tests/ # 测试用例
│ └── test_backup.sh
└── README.md
模块化编程实践:
bash复制# lib/utils.sh
#!/bin/bash
log() {
echo "[$(date)] $@" >> "/var/log/${0##*/}.log"
}
validate_input() {
[[ "$1" =~ ^[a-zA-Z0-9_-.]+$ ]] && return 0
return 1
}
# bin/backup.sh
#!/bin/bash
source "$(dirname "$0")/../lib/utils.sh"
log "备份脚本启动"
validate_input "$1" || { log "无效输入"; exit 1; }
单元测试示例:
bash复制#!/bin/bash
# tests/test_utils.sh
source ../lib/utils.sh
test_log_creation() {
log "测试消息"
[ -f "/var/log/test_utils.log" ] && echo "PASS" || echo "FAIL"
}
test_input_validation() {
validate_input "valid_name" && echo "PASS" || echo "FAIL"
validate_input "invalid@name" && echo "FAIL" || echo "PASS"
}
# 执行测试
echo "运行测试套件:"
test_log_creation
test_input_validation
16. 交互式脚本开发技巧
用户交互增强:
bash复制#!/bin/bash
# 菜单驱动界面
PS3='请选择操作: '
options=("系统信息" "磁盘检查" "网络测试" "退出")
select opt in "${options[@]}"; do
case $opt in
"系统信息")
echo -e "\n$(uptime)"
echo "CPU负载: $(cat /proc/loadavg)"
;;
"磁盘检查")
df -h | while read -r line; do
echo " $line"
done
;;
"网络测试")
read -p "输入测试地址: " host
ping -c 4 "$host" | grep "packet loss"
;;
"退出")
break
;;
*) echo "无效选项 $REPLY";;
esac
done
进度显示实现:
bash复制# 文本进度条
progress_bar() {
local duration=${1:-10}
local width=${2:-50}
local increment=$((100/width))
for ((i=0; i<=width; i++)); do
percentage=$((i*increment))
printf "\r[%-${width}s] %d%%" \
"$(printf '#%.0s' $(seq 1 $i))" \
"$percentage"
sleep "$(echo "scale=4; $duration/$width" | bc)"
done
echo
}
progress_bar 5 30
颜色和格式控制:
bash复制# 定义颜色代码
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
# 使用示例
echo -e "${RED}错误:${NC} 文件不存在"
echo -e "${GREEN}成功:${NC} 操作完成"
# 光标控制
clear_line() {
printf "\033[2K\r" # 清除整行
}
# 动态更新显示
for i in {1..10}; do
clear_line
printf "处理中... %d/10" "$i"
sleep 0.5
done
clear_line
echo "处理完成"
17. 跨平台Shell编程
处理平台差异:
bash复制#!/bin/bash
# 检测操作系统
case "$OSTYPE" in
linux*) OS="Linux" ;;
darwin*) OS="Mac" ;;
cygwin*) OS="Cygwin" ;;
msys*) OS="Windows" ;;
*) OS="Unknown" ;;
esac
# 平台特定命令
case "$OS" in
Linux)
open() { xdg-open "$@" &>/dev/null; }
get_ip() { ip addr | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d/ -f1; }
;;
Mac)
open() { /usr/bin/open "$@" &>/dev/null; }
get_ip() { ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}'; }
;;
*)
echo "不支持的操作系统: $OS"
exit 1
;;
esac
# 使用通用接口
echo "IP地址: $(get_ip)"
open "http://example.com"
WSL集成技巧:
bash复制#!/bin/bash
# 检测是否在WSL中运行
if grep -qEi "(Microsoft|WSL)" /proc/version &>/dev/null; then
echo "运行在WSL环境"
# 访问Windows路径
win_user=$(cmd.exe /c "echo %USERNAME%" 2>/dev/null | tr -d '\r')
win_path="/mnt/c/Users/$win_user"
# 在Windows中打开文件
wsl_open() {
local path=$1
if [[ "$path" =~ ^/mnt/[a-z]/ ]]; then
cmd.exe /c "start \"\" \"${path//\//\\}\""
else
xdg-open "$path"
fi
}
fi
18. Shell与DevOps工具集成
Docker集成示例:
bash复制#!/bin/bash
# 构建并运行容器
docker build -t myapp:latest .
docker run -d -p 8080:80 --name myapp_instance myapp:latest
# 健康检查
for i in {1..10}; do
if curl -s http://localhost:8080/health | grep -q "OK"; then
echo "应用启动成功"
break
fi
sleep 2
done
# 日志收集
docker logs myapp_instance > app.log 2>&1
Kubernetes操作脚本:
bash复制#!/bin/bash
# 批量部署YAML文件
deploy_to_k8s() {
local namespace=$1
shift
local files=("$@")
kubectl create namespace "$namespace" 2>/dev/null || true
for file in "${files[@]}"; do
echo "部署 $file 到 $namespace"
kubectl apply -n "$namespace" -f "$file"
# 等待部署完成
if grep -q "kind: Deployment" "$file"; then
deployment=$(grep "name:" "$file" | awk '{print $2}')
kubectl rollout status -n "$namespace" "deployment/$deployment"
fi
done
}
# 使用示例
deploy_to_k8s staging ./k8s/{deployment,service}.yaml
CI/CD集成:
bash复制#!/bin/bash
# GitLab CI示例脚本
BRANCH="$CI_COMMIT_REF_NAME"
VERSION="${CI_COMMIT_SHA:0:8}"
# 构建
docker build -t "registry.example.com/app:$VERSION" .
docker push "registry.example.com/app:$VERSION"
# 环境判断
case "$BRANCH" in
master)
kubectl set image "deployment/app" "app=registry.example.com/app:$VERSION" -n production
;;
staging)
kubectl set image "deployment/app" "app=registry.example.com/app:$VERSION" -n staging
;;
*)
echo "跳过非主线分支部署"
;;
esac
19. 性能监控与分析脚本
系统性能快照:
bash复制#!/bin/bash
# 获取系统性能快照
SNAPSHOT_FILE="/tmp/system_snapshot_$(date +%Y%m%d_%H%M%S).log"
{
echo "===== 系统概览 ====="
uptime
echo -e "\n===== CPU使用率 ====="
top -bn1 | head -10
echo -e "\n===== 内存使用 ====="
free -h
echo -e "\n===== 磁盘空间 ====="
df -h
echo -e "\n===== IO统计 ====="
iostat -dx 1 5
echo -e "\n===== 网络连接 ====="
netstat -tulnp
} > "$SNAPSHOT_FILE"
echo "系统快照已保存到 $SNAPSHOT_FILE"
进程资源监控:
bash复制#!/bin/bash
# 监控指定进程资源使用
PID=${1:-1}
INTERVAL=${2:-5}
LOG_FILE="process_monitor_$PID.log"
echo "监控进程 $PID,间隔 $INTERVAL 秒" > "$LOG_FILE"
echo "时间戳 CPU(%) 内存(MB) 线程数 文件描述符" >> "$LOG_FILE"
while ps -p "$PID" > /dev/null; do
timestamp=$(date +"%Y-%m-%d %H:%M:%S")
stats=$(ps -p "$PID" -o %cpu,rssize,nlwp,fdsize --no-headers)
echo "$timestamp $stats" | awk '{printf "%s %.1f %.1f %d %d\n", $1, $2, $3/1024, $4, $5}' >> "$LOG_FILE"
sleep "$INTERVAL"
done
echo "进程 $PID 已结束" >> "$LOG_FILE"
使用awk分析日志:
bash复制#!/bin/bash
# 分析Nginx访问日志
LOG_FILE="/var/log/nginx/access.log"
# 统计状态码
awk '{print $9}' "$LOG_FILE" | sort | uniq -c | sort -rn
# 最频繁的IP
awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -10
# 响应时间分析
awk '
{
resp_time = $(NF-1)
if (resp_time < 1) bucket["<1s"]++
else if (resp_time < 3) bucket["1-3s"]++
else if (resp_time < 10) bucket["3-10s"]++
else bucket[">10s"]++
}
END {
for (b in bucket) print b, bucket[b]
}
' "$LOG_FILE"
20. Shell脚本的未来与进阶方向
Shell与现代开发:
-
云原生环境下的Shell角色:
- 作为初始化容器的轻量级脚本
- 在CI/CD流水线中执行环境准备
- 基础设施即代码(IaC)的补充工具
-
与配置管理工具集成:
bash复制# Ansible与Shell结合
ansible all -i inventory.ini -m shell -a \
"grep 'memory' /proc/meminfo | awk '{print \$2}'"
# Terraform本地执行器
resource "null_resource" "setup" {
provisioner "local-exec" {
command = <<-EOT
#!/bin/bash
echo "配置IP $(aws_instance.web.private_ip)" > config.ini
EOT
}
}
-
学习路线建议:
- 掌握Bash 5.0+新特性:关联数组、进程替换增强
- 学习POSIX Shell兼容性编写
- 了解zsh/fish等现代Shell的特性
- 结合Python处理复杂逻辑,Shell专注流程控制
-
性能关键型场景替代方案:
bash复制# 当Shell性能不足时考虑:
# - 使用AWK处理文本
# - 用Python处理复杂数据结构
# - 用Go/Rust编写高性能组件
# - 通过Shell粘合各种专业工具
# 示例:混合编程
#!/bin/bash
# 使用Python生成数据,Shell处理流程
dataset=$(python3 -c '
import random
print("\n".join(str(random.gauss(0, 1)) for _ in range(100)))
')
echo "$dataset" | awk '
{
sum += $1
sumsq += $1^2
}
END {
mean = sum/NR
stddev = sqrt(sumsq/NR - mean^2)
print "平均值:", mean
print "标准差:", stddev
}
'
