Shell脚本编程入门到进阶:自动化运维必备技能

Shell脚本是Linux系统管理和自动化运维的必备技能。本文将带你从入门到进阶,掌握Shell脚本编程的核心知识。

1. 基础语法

Hello World

#!/bin/bash
# 这是一个注释
echo "Hello World"

变量

#!/bin/bash

# 定义变量(不能有空格)
name="Alice"
age=30

# 使用变量($前缀)
echo "Name: $name"
echo "Age: ${age}"

# 只读变量
readonly PI=3.14159

# 环境变量
export PATH=$PATH:/new/path

特殊变量

$0    # 脚本名称
$1-$9  # 第1-9个参数
${10}  # 第10个参数
$#    # 参数个数
$*    # 所有参数
$@    # 所有参数(保持引用)
$?    # 上一条命令的退出状态
$$    # 当前进程ID
$!    # 后台进程ID

2. 条件判断

if语句

#!/bin/bash

if [ "$age" -gt 18 ]; then
    echo "Adult"
elif [ "$age" -eq 18 ]; then
    echo "Just turned 18"
else
    echo "Minor"
fi

case语句

#!/bin/bash

case "$1" in
    start)
        echo "Starting service..."
        ;;
    stop)
        echo "Stopping service..."
        ;;
    restart)
        echo "Restarting service..."
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac

测试条件

# 文件测试
[ -f file.txt ]    # 是普通文件
[ -d dir/ ]        # 是目录
[ -r file.txt ]    # 可读
[ -w file.txt ]    # 可写
[ -x script.sh ]   # 可执行
[ -e file.txt ]    # 文件存在
[ -s file.txt ]    # 文件非空

# 字符串测试
[ -z "$str" ]      # 字符串为空
[ -n "$str" ]      # 字符串非空
[ "$a" = "$b" ]    # 字符串相等
[ "$a" != "$b" ]   # 字符串不等

3. 循环

for循环

#!/bin/bash

# 遍历列表
for file in *.txt; do
    echo "Processing $file"
done

# 遍历数字
for i in {1..10}; do
    echo "Number: $i"
done

# C语言风格
for ((i=0; i<10; i++)); do
    echo "i=$i"
done

while循环

#!/bin/bash

count=1
while [ $count -le 5 ]; do
    echo "Count: $count"
    ((count++))
done

until循环

#!/bin/bash

count=1
until [ $count -gt 5 ]; do
    echo "Count: $count"
    ((count++))
done

4. 函数

#!/bin/bash

# 定义函数
function greet() {
    local name=$1
    echo "Hello, $name!"
}

# 调用函数
greet "Alice"
greet "Bob"

# 带返回值
function add() {
    local result=$(( $1 + $2 ))
    echo $result
}

sum=$(add 10 20)
echo "Sum: $sum"

5. 数组

#!/bin/bash

# 定义数组
fruits=("apple" "banana" "cherry")

# 访问元素
echo ${fruits[0]}    # apple
echo ${fruits[@]}    # 所有元素
echo ${#fruits[@]}   # 数组长度

# 添加元素
fruits+=("orange")

# 遍历数组
for fruit in "${fruits[@]}"; do
    echo "Fruit: $fruit"
done

6. 字符串处理

#!/bin/bash

str="Hello World"

# 长度
echo ${#str}    # 11

# 子串
echo ${str:0:5}  # Hello
echo ${str:6}    # World

# 替换
echo ${str/World/Bash}  # Hello Bash
echo ${str//l/L}       # HeLLo WorLd

# 删除前缀
echo ${str#Hello}    #  World
echo ${str##Hello}   #  World

# 删除后缀
echo ${str%World}    # Hello
echo ${str%%World}   # Hello

7. 实战案例

批量重命名

#!/bin/bash

count=1
for file in *.jpg; do
    new_name=$(printf "photo_%03d.jpg" $count)
    mv "$file" "$new_name"
    ((count++))
done

日志分析

#!/bin/bash

logfile="/var/log/nginx/access.log"

# 统计状态码
echo "Status Code Distribution:"
awk '{print $9}' "$logfile" | sort | uniq -c | sort -nr

# 统计IP访问量
echo "\nTop 10 IPs:"
awk '{print $1}' "$logfile" | sort | uniq -c | sort -nr | head -10

自动备份

#!/bin/bash

backup_dir="/backup"
timestamp=$(date +%Y%m%d_%H%M%S)
archive="backup_$timestamp.tar.gz"

tar -czf "$backup_dir/$archive" /important/data

# 保留最近7天备份
find "$backup_dir" -name "backup_*.tar.gz" -mtime +7 -delete

系统监控

#!/bin/bash

# CPU使用率
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)

# 内存使用率
mem_usage=$(free | grep Mem | awk '{print ($3/$2)*100}')

# 磁盘使用率
disk_usage=$(df -h / | awk 'NR==2 {print $5}' | cut -d'%' -f1)

echo "CPU: $cpu_usage%"
echo "Memory: $mem_usage%"
echo "Disk: $disk_usage%"

8. 调试技巧

#!/bin/bash

# 调试模式
set -x  # 开启调试
# 你的代码
set +x  # 关闭调试

# 错误退出
set -e  # 任何命令失败立即退出
set -u  # 使用未定义变量时报错

# 检查语法
bash -n script.sh

# 跟踪执行
bash -x script.sh

9. 最佳实践

  • 使用shebang:#!/bin/bash
  • 变量引用加引号:"$variable"
  • 使用函数:模块化代码
  • 错误处理:检查命令返回值
  • 日志记录:记录关键操作
  • 注释清晰:说明复杂逻辑

10. 部署自动化

#!/bin/bash

# 部署脚本示例
APP_DIR="/var/www/myapp"
BACKUP_DIR="/backup"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# 1. 备份当前版本
tar -czf "$BACKUP_DIR/app_$TIMESTAMP.tar.gz" -C "$APP_DIR" .

# 2. 拉取最新代码
cd $APP_DIR
git pull origin main

# 3. 安装依赖
pip install -r requirements.txt

# 4. 运行数据库迁移
python manage.py migrate

# 5. 收集静态文件
python manage.py collectstatic --noinput

# 6. 重启服务
sudo systemctl restart gunicorn

echo "Deployment completed at $(date)"

总结

Shell脚本虽然语法简单,但功能强大。掌握Shell脚本,可以实现:

  • 自动化部署:CI/CD流水线
  • 系统监控:定时检查系统状态
  • 日志分析:批量处理日志文件
  • 备份恢复:自动化备份策略
📖 进阶学习:学习Awk、Sed等文本处理工具,掌握Expect进行交互式自动化,以及使用Ansible进行配置管理。

发表评论