Shell脚本编程完全指南:从基础到自动化项目实战

发布于:2025-03-30 ⋅ 阅读:(68) ⋅ 点赞:(0)

一、Shell脚本基础概念

Shell脚本(Shell Script)是通过文本文件编写的命令集合,由Shell命令解释器逐行解析执行。作为Unix/Linux系统的核心自动化工具,它能完成:

  • 系统管理任务自动化

  • 复杂命令序列的封装

  • 文件批量处理

  • 服务状态监控等

典型应用场景:

#!/bin/bash
# 自动备份网站目录并删除7天前的备份
tar -czf /backup/web_$(date +%Y%m%d).tar.gz /var/www/html
find /backup -name "web_*.tar.gz" -mtime +7 -exec rm {} \;

二、Shell命令解释器

  1. 常见Shell类型

    • Bash (Bourne-Again Shell):Linux默认Shell

    • Zsh:功能增强型Shell

    • Ksh (Korn Shell):Unix传统Shell

  2. Shebang声明

#!/usr/bin/env bash  # 推荐写法,自动查找bash路径
#!/bin/bash         # 传统写法

三、变量操作

1. 变量基础

name="John"         # 定义变量
echo $name          # 输出变量
echo ${name}        # 推荐写法,明确变量边界

2. 环境变量

export PATH=$PATH:/custom/bin  # 设置环境变量
env | grep LANG                # 查看环境变量

3. 特殊变量

$0   脚本名称
$1   第一个参数
$#   参数个数
$@   所有参数列表
$?   上条命令退出状态

4.Shell数值运算方法对比表

运算方式 语法示例 特点说明 适用场景
$(( )) echo $((a + b)) 1. 支持整数运算
2. 无需转义符号
常规算术运算
let let "result=a*b" 1. 支持复合运算
2. 直接修改变量
需要保存运算结果
expr expr $a \* $b 1. 兼容性最好
2. 需要转义特殊符号
老旧系统环境
bc echo "scale=2;3/7" | bc 1. 支持浮点运算
2. 可设定精度
精确计算需求

四、流程控制

1.状态检测
检测项 运算符 示例 说明
空字符串 -z [ -z "$var" ] 变量值为空或未定义时返回真
非空字符串 -n [[ -n $str ]] 变量有非空值时返回真
存在性检查 = [ "$var" = "exists" ] 需要显式值对比

2. 条件判断

if [ -f "/path/file" ]; then
    echo "文件存在"
elif [ -d "/path" ]; then
    echo "目录存在"
else
    echo "路径无效"
fi

# 使用双括号支持高级比较
if (( $# > 2 )); then
    echo "参数过多"
fi

3. 多条件判断

case $OS in
    "Linux")
        echo "使用apt/yum"
        ;;
    "Darwin")
        echo "使用brew"
        ;;
    *)
        echo "未知系统"
esac

4.数值比较运算符表

运算符 数学符号 描述 示例 兼容性
-eq = 等于 [ "$a" -eq 5 ] 所有Shell
-ne 不等于 [[ "$a" -ne 10 ]] 所有Shell
-gt > 大于 (( a > b )) Bash/Zsh
-ge 大于等于 [ $a -ge $b ] 所有Shell
-lt < 小于 [[ $a -lt 20 ]] 所有Shell
-le 小于等于 (( a <= b )) Bash/Zsh

5.字符串操作对照表

运算符 功能描述 标准写法 增强写法(双方括号)
= 字符串相等 [ "$s1" = "$s2" ] [[ $s1 == $s2 ]]
!= 字符串不等 [ "$s1" != "text" ] [[ $s1 != pattern* ]]
> 按ASCII码顺序大于 不支持 [[ "apple" > "banana" ]]
< 按ASCII码顺序小于 不支持 [[ "cat" < "dog" ]]

五、循环结构

1. For循环

for i in {1..5}; do
    echo "第$i次循环"
done

# 遍历文件
for file in *.log; do
    gzip "$file"
done

2. While循环

counter=0
while [ $counter -lt 5 ]; do
    echo $counter
    ((counter++))
done

# 读取文件内容
while IFS= read -r line; do
    echo "处理: $line"
done < data.txt

六、函数编程

function calc_sum {
    local sum=$(( $1 + $2 ))  # 局部变量
    return $sum
}

calc_sum 10 20
echo "计算结果: $?"

七、脚本间调用

1. 调用方式

# 子进程执行
./subscript.sh param1 param2

# 当前进程执行
source config.sh

2. 参数传递示例

main.sh:

#!/bin/bash
echo "主脚本启动"
./sub.sh "参数1" "参数2"

八、C语言集成调用

#include <stdlib.h>

int main() {
    //execl("./test.sh","b.sh",(char*)0)
    int ret = system("./backup.sh");
    if (WIFEXITED(ret)) {
        printf("退出码: %d\n", WEXITSTATUS(ret));
    }
    return 0;
}

编译执行:

gcc -o caller caller.c
./caller

九、文本处理三剑客

1. Sed流编辑器

# 替换文本内容
sed 's/old/new/g' input.txt > output.txt

# 删除空行
sed '/^$/d' file.txt

2. Awk数据处理器

# 统计文件行数
awk 'END{print NR}' data.log

# 字段处理
awk -F',' '{print $1, $3}' users.csv

3. 正则表达式实战

# 匹配IP地址
grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}' access.log

# 提取邮箱地址
awk '/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/ {print $0}' contacts.txt

十、高级技巧扩展

  1. 调试技巧

set -x   # 开启调试模式
set +x   # 关闭调试
  1. 错误处理

set -euo pipefail  # 严格模式
trap "echo 发生错误" ERR
  1. 性能优化

# 避免频繁启动子进程
while read line; do
    process "$line"
done < <(grep pattern bigfile.txt)

浮点运算方法对比

方法 示例 精度控制 输出示例
bc echo "3.14+2.718" | bc scale=N设置小数位 5.858
awk awk 'BEGIN{print 1/3}' PREC变量控制 0.333333
printf printf "%.2f" 3.1415 格式字符串指定 3.14
dc echo "4k 3 7 / p" | dc k命令设置精度 0.4285

十一、最佳实践建议

  1. 脚本头部添加版本和说明注释
  2. 重要操作添加确认提示
  3. 使用$(cmd)代替反引号
  4. 处理含空格路径时用双引号包裹变量
  5. 设置合理的执行权限(755/700)
  6. 常见错误对照表
    错误示例 正确写法 问题分析
    [ $var = text ] [ "$var" = "text" ] 变量未引号导致空格解析错误
    [[ 100 > 20 ]] [[ "100" -gt 20 ]] 字符串与数值比较类型混淆
    echo $num1+$num2 echo $((num1+num2)) 未使用算术展开导致字符串拼接
    if [ ! -z $var ]; then if [[ -n "$var" ]]; then 双重否定导致逻辑不清晰

十二、服务器健康监控与自动化维护系统

1. 智能监控告警
check_cpu_usage() {
    local threshold=85
    local usage=$(top -bn1 | awk '/Cpu/{print 100-$8}')
    
    # 动态调整阈值
    [ $usage -gt 90 ] && threshold=95
    
    if (( $(echo "$usage > $threshold" | bc) )); then
        send_alert "CPU过载警告" "当前使用率: ${usage}%"
    fi
}
2. 日志分析引擎
analyze_ssh_logins() {
    awk '
    /Accepted publickey/ {
        users[$9]++
        ips[$11]++
    }
    END {
        print "成功登录统计:"
        print "用户\t次数"
        for(u in users) print u "\t" users[u]
        print "\nIP统计:"
        for(ip in ips) print ip "\t" ips[ip]
    }' /var/log/auth.log
}
3. 自动维护机器人
clean_old_files() {
    # 安全删除7天前临时文件
    find /tmp -type f -name "*.tmp" \
        -mtime +7 \
        -exec sh -c 'echo "删除: {}"; rm {}' \;
}
4.主程序
#!/bin/bash
# 主调度程序

# 加载模块
source modules/system_monitor.sh
source modules/log_analyzer.sh
source modules/auto_cleaner.sh
source modules/backup_manager.sh

# 初始化环境
mkdir -p logs reports backups

while true; do
    check_cpu
    check_memory
    check_disk
    analyze_errors "/var/log/nginx/error.log"
    clean_tmp_files
    if [ $(date +%H) -eq 2 ]; then  # 每天凌晨2点执行
        backup_database
    fi
    sleep 300  # 5分钟轮询
done

附录:常用资源