> Linux Shell脚本自动化:从入门到精通实战指南 _

Linux Shell脚本自动化:从入门到精通实战指南

前言

在当今的IT运维和开发领域,自动化已经成为提高效率的关键。而Linux Shell脚本作为最基础且强大的自动化工具,掌握其精髓对于每个技术人员都至关重要。本文将深入探讨Shell脚本的实战应用,带你从基础入门到高级技巧,全面提升自动化运维能力。

Shell脚本基础核心概念

Shell环境与选择

在开始编写脚本前,我们需要了解不同的Shell环境。虽然bash是目前最流行的Shell,但还有其他选择:

#!/bin/bash
# 这是一个标准的bash脚本开头

#!/bin/zsh
# 或者使用zsh shell

#!/usr/bin/env bash
# 更通用的指定方式

变量与数据类型

Shell中的变量处理有其独特之处:

#!/bin/bash

# 定义变量
name="Shell Scripting"
version=1.0

# 只读变量
readonly MAX_RETRY=3

# 使用变量
echo "当前教程:$name 版本:$version"

# 命令替换
current_date=$(date +%Y-%m-%d)
echo "当前日期:$current_date"

条件判断与流程控制

条件判断是脚本逻辑的核心:

#!/bin/bash

# 数值比较
if [ $# -eq 0 ]; then
    echo "请输入参数"
elif [ $# -gt 5 ]; then
    echo "参数过多"
else
    echo "参数数量合适"
fi

# 文件测试
file="/etc/passwd"
if [ -f "$file" ]; then
    echo "$file 存在且是普通文件"
fi

# case语句
case $1 in
    start)
        echo "启动服务"
        ;;
    stop)
        echo "停止服务"
        ;;
    *)
        echo "用法: $0 {start|stop}"
        ;;
esac

高级Shell编程技巧

函数编程实践

函数让代码更加模块化和可重用:

#!/bin/bash

# 定义函数
log_message() {
    local level=$1
    local message=$2
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')

    echo "[$timestamp] [$level] $message" >> /var/log/myscript.log
}

# 使用函数
log_message "INFO" "脚本开始执行"

# 带返回值的函数
check_disk_usage() {
    local usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
    echo $usage
}

disk_usage=$(check_disk_usage)
if [ $disk_usage -gt 90 ]; then
    log_message "WARNING" "磁盘使用率超过90%"
fi

数组与关联数组

数组在数据处理中非常有用:

#!/bin/bash

# 普通数组
services=("nginx" "mysql" "redis")
echo "第一个服务: ${services[0]}"

# 遍历数组
for service in "${services[@]}"; do
    echo "检查服务: $service"
    systemctl status $service > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "$service 运行正常"
    else
        echo "$service 未运行"
    fi
done

# 关联数组(bash 4.0+)
declare -A config
config["host"]="localhost"
config["port"]=3306
config["user"]="admin"

echo "数据库主机: ${config[host]}"

信号处理与错误处理

健壮的脚本需要良好的错误处理机制:

#!/bin/bash

set -euo pipefail  # 严格模式

# 信号处理
trap 'cleanup' EXIT
trap 'echo "中断执行"; exit 1' INT TERM

cleanup() {
    echo "执行清理操作..."
    # 清理临时文件等
}

# 错误处理函数
handle_error() {
    local line=$1
    local command=$2
    echo "错误发生在第 $line 行: $command"
    exit 1
}

trap 'handle_error ${LINENO} "$BASH_COMMAND"' ERR

# 示例可能失败的操作
mkdir -p /tmp/test_dir
cd /tmp/test_dir || exit 1

实战案例:系统监控脚本

服务器健康检查

#!/bin/bash

set -euo pipefail

LOG_FILE="/var/log/server_health.log"
THRESHOLD_CPU=80
THRESHOLD_MEM=85
THRESHOLD_DISK=90

# 记录日志函数
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}

# 检查CPU使用率
check_cpu() {
    local cpu_usage=$(top -bn1 | grep "Cpu(s)" | sed 's/.*, *\([0-9.]*\)%* id.*/\1/' | awk '{print 100 - $1}')
    if (( $(echo "$cpu_usage > $THRESHOLD_CPU" | bc -l) )); then
        log "警告: CPU使用率 ${cpu_usage}% 超过阈值 ${THRESHOLD_CPU}%"
        return 1
    fi
    log "CPU使用率正常: ${cpu_usage}%"
    return 0
}

# 检查内存使用率
check_memory() {
    local mem_info=$(free | grep Mem)
    local total_mem=$(echo $mem_info | awk '{print $2}')
    local used_mem=$(echo $mem_info | awk '{print $3}')
    local mem_usage=$(echo "scale=2; $used_mem * 100 / $total_mem" | bc)

    if (( $(echo "$mem_usage > $THRESHOLD_MEM" | bc -l) )); then
        log "警告: 内存使用率 ${mem_usage}% 超过阈值 ${THRESHOLD_MEM}%"
        return 1
    fi
    log "内存使用率正常: ${mem_usage}%"
    return 0
}

# 检查磁盘空间
check_disk() {
    local disk_usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
    if [ $disk_usage -gt $THRESHOLD_DISK ]; then
        log "警告: 磁盘使用率 ${disk_usage}% 超过阈值 ${THRESHOLD_DISK}%"
        return 1
    fi
    log "磁盘使用率正常: ${disk_usage}%"
    return 0
}

# 主监控函数
main() {
    log "开始服务器健康检查"

    check_cpu
    check_memory
    check_disk

    log "健康检查完成"
}

# 执行主函数
main "$@"

自动化备份脚本


#!/bin/bash

set -euo pipefail

# 配置变量
BACKUP_DIR="/backup"
RETENTION_DAYS=7
DATE_FORMAT=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/backup_${DATE_FORMAT}.log"

# 需要备份的目录
BACKUP_SOURCES=(
    "/etc"
    "/home"
    "/var/www"
)

# 数据库配置
DB_USER="backup_user"
DB_PASS="secure_password"
DB_NAME="important_db"

# 记录日志
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}

# 创建备份目录
create_backup_dir() {
    local dir="${BACKUP_DIR}/${DATE_FORMAT}"
    mkdir -p "$dir"
    echo "$dir"
}

# 备份文件系统
backup_files() {
    local backup_dir=$1
    log "开始文件系统备份"

    for source in "${BACKUP_SOURCES[@]}"; do
        if [ -d "$source" ]; then
            local target_name=$(basename "$source")
            local backup_file="${backup_dir}/${target_name}_${DATE_FORMAT}.tar.gz"

            log "备份: $source → $backup_file"
            tar -czf "$backup_file" "$source" 2>> $LOG_FILE

            if [ $? -eq 0 ]; then
                log "成功备份: $source"
            else
                log "错误: 备份 $source 失败"
                return 1
            fi
        else
            log "警告: 备份源不存在: $source"
        fi
    done
}

# 备份数据库
backup_database() {
    local backup_dir=$1
    local db_file="${backup_dir}/database_${DATE_FORMAT}.sql.gz"

    log "开始数据库备份"

    if command -v mysqldump >/dev/null 2>&1; then
        mysqldump -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" | gzip > "$db_file" 2>> $LOG_FILE

        if [ $? -eq 0 ]; then
            log "数据库备份成功

> 文章统计_

字数统计: 计算中...
阅读时间: 计算中...
发布日期: 2025年09月11日
浏览次数: 48 次
评论数量: 0 条
文章大小: 计算中...

> 评论区域 (0 条)_

发表评论

1970-01-01 08:00:00 #
1970-01-01 08:00:00 #
#
Hacker Terminal
root@www.qingsin.com:~$ welcome
欢迎访问 百晓生 联系@msmfws
系统状态: 正常运行
访问权限: 已授权
root@www.qingsin.com:~$