第18章:Shell 脚本编程基础

恭喜你已经掌握了 Linux 系统管理的核心技能。现在,是时候将这些命令"串联"起来,通过 Shell 脚本 实现自动化,大幅提升运维效率。在 openEuler 环境中,Bash 脚本是自动化任务、系统维护、部署流程的基石。本章将带你从零开始,写出第一个"会思考"的脚本。

🌟 本章目标

  • 理解 Shell 脚本的作用与执行方式
  • 掌握脚本结构:#!/bin/bash 与权限设置
  • 学会定义和使用变量(普通变量、环境变量、位置参数)
  • 使用 if 语句进行条件判断(文件、字符串、数字)
  • 使用 forwhile 循环批量处理任务
  • 定义和调用函数,提高代码复用性
  • 实战:编写一个系统资源监控与告警脚本

18.1 什么是 Shell 脚本?

Shell 脚本 是一个包含一系列 Shell 命令的文本文件,可以像程序一样被批量执行

✅ 为什么需要脚本?

  • 自动化重复任务:备份、日志清理、服务检查
  • 减少人为错误
  • 提高效率:一键完成多步操作
  • 可复用、可分享:团队协作的"运维配方"

💬 类比:

  • 手动执行命令 = 一步步做菜
  • Shell 脚本 = 写下菜谱,让别人或机器照着做

18.2 第一个 Shell 脚本

步骤1:创建脚本文件

bash 复制代码
vim hello.sh

步骤2:编写内容

bash 复制代码
#!/bin/bash
# 这是我的第一个 Shell 脚本
echo "Hello, openEuler!"
echo "当前时间:$(date)"
echo "当前用户:$(whoami)"

步骤3:添加可执行权限

bash 复制代码
chmod +x hello.sh

步骤4:执行脚本

bash 复制代码
./hello.sh

输出:

复制代码
Hello, openEuler!
当前时间:2024年04月06日 星期六 10:30:00
当前用户:zhangsan

✅ 脚本成功运行!


18.3 脚本结构详解

✅ 1. Shebang(#!/bin/bash

  • 必须位于第一行
  • 告诉系统用哪个解释器运行脚本
  • 常见:
    • #!/bin/bash:Bash
    • #!/bin/sh:标准 Shell
    • #!/usr/bin/env python3:Python

⚠️ 如果没有 Shebang,需显式调用解释器:

bash 复制代码
bash hello.sh

✅ 2. 注释(#

  • # 后的内容为注释,不会被执行
  • 用于说明脚本功能、作者、修改记录
bash 复制代码
# Author: zhangsan
# Date: 2024-04-06
# Description: 系统信息收集脚本

✅ 3. 执行方式

方式 命令 特点
直接执行 ./script.sh x 权限
调用解释器 bash script.sh 无需 x 权限
源码执行 source script.sh. script.sh 在当前 Shell 环境执行,变量会保留

18.4 变量(Variables)

变量用于存储数据,是脚本的"记忆"。

🔧 定义变量

bash 复制代码
name="zhangsan"
age=25
pi=3.14
  • 变量名区分大小写
  • 不能有空格(name = "zhangsan" 错误!)
  • 可用 export 变为环境变量

🔍 使用变量

bash 复制代码
echo "姓名:$name"
echo "年龄:${age}岁"   # ${} 更安全,避免歧义

🧩 特殊变量

变量 说明
$0 脚本名
$1, $2, ... 第1、2个参数
$# 参数个数
$@ 所有参数(保留空格)
$* 所有参数(合并为一个字符串)
$$ 当前脚本的 PID
$? 上一条命令的退出状态(0=成功)

实战:参数传递脚本

bash 复制代码
vim greet.sh
bash 复制代码
#!/bin/bash
echo "脚本名:$0"
echo "参数个数:$#"
echo "第一个参数:$1"
echo "所有参数:$@"

执行:

bash 复制代码
chmod +x greet.sh
./greet.sh 张三 李四 王五

输出:

复制代码
脚本名:./greet.sh
参数个数:3
第一个参数:张三
所有参数:张三 李四 王五

18.5 条件判断:if 语句

if 让脚本具备"判断能力"。

基本语法

bash 复制代码
if 条件; then
    命令1
    命令2
elif 条件; then
    命令3
else
    命令4
fi

✅ 使用 test[ ]

bash 复制代码
if [ -f "/etc/passwd" ]; then
    echo "passwd 文件存在"
fi

⚠️ [ 后、] 前必须有空格!


🔍 常见判断条件

类型 条件 说明
文件 [ -f file ] 是普通文件
[ -d dir ] 是目录
[ -r file ] 可读
[ -w file ] 可写
[ -x file ] 可执行
字符串 [ -z str ] 字符串为空
[ -n str ] 字符串非空
[ "str1" = "str2" ] 相等
[ "str1" != "str2" ] 不等
数字 [ 1 -eq 1 ] 等于
[ 2 -gt 1 ] 大于
[ 1 -lt 2 ] 小于
[ 1 -ge 1 ] 大于等于
[ 1 -le 2 ] 小于等于

实战:检查服务状态

bash 复制代码
#!/bin/bash
service=$1

if systemctl is-active --quiet $service; then
    echo "$service 正在运行"
else
    echo "$service 未运行"
fi

保存为 check_service.sh,执行:

bash 复制代码
./check_service.sh sshd

18.6 循环:forwhile

🔁 for 循环(已知范围)

bash 复制代码
for i in 1 2 3 4 5; do
    echo "数字:$i"
done
遍历文件
bash 复制代码
for file in /tmp/*.txt; do
    if [ -f "$file" ]; then
        echo "处理文件:$file"
    fi
done
C 风格 for
bash 复制代码
for ((i=1; i<=5; i++)); do
    echo "计数:$i"
done

🔄 while 循环(条件满足时继续)

bash 复制代码
count=1
while [ $count -le 5 ]; do
    echo "当前:$count"
    count=$((count + 1))
done
实用:监控 CPU 使用率
bash 复制代码
while true; do
    cpu=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
    echo "CPU 使用率:$cpu%"
    sleep 2
done

18.7 函数(Functions)

函数用于封装可复用的代码块。

定义函数

bash 复制代码
function backup() {
    echo "开始备份..."
    tar -czf /backup/etc-$(date +%F).tar.gz /etc
    echo "备份完成"
}

# 或省略 function 关键字
log() {
    echo "[$(date)] $1" >> /var/log/myscript.log
}

调用函数

bash 复制代码
backup
log "系统检查完成"

18.8 实战:系统资源监控脚本

需求

  • 检查磁盘、内存使用率
  • 超过 80% 时输出警告
  • 记录日志

脚本:monitor.sh

bash 复制代码
#!/bin/bash
# 系统监控脚本

LOG_FILE="/var/log/monitor.log"
THRESHOLD=80

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE
}

check_disk() {
    usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
    if [ $usage -gt $THRESHOLD ]; then
        log "WARNING: 根分区使用率 $usage%"
        echo "警告:磁盘使用率过高!"
    else
        log "OK: 磁盘使用率 $usage%"
    fi
}

check_memory() {
    usage=$(free | grep Mem | awk '{printf("%.0f", $3/$2 * 100)}')
    if [ $usage -gt $THRESHOLD ]; then
        log "WARNING: 内存使用率 $usage%"
        echo "警告:内存使用率过高!"
    else
        log "OK: 内存使用率 $usage%"
    fi
}

# 主程序
log "=== 系统监控开始 ==="
check_disk
check_memory
log "=== 系统监控结束 ==="

使用

bash 复制代码
sudo chmod +x monitor.sh
sudo ./monitor.sh
tail /var/log/monitor.log

✅ 一个实用的自动化监控工具诞生!


✅ 本章小结

结构 语法 说明
Shebang #!/bin/bash 指定解释器
变量 name="value" 存储数据
条件 if [ 条件 ]; then ... fi 判断执行
循环 for, while 重复执行
函数 function name() { ... } 代码复用
特殊变量 $1, $?, $@ 脚本元信息

📝 课后练习

  1. 编写一个脚本 greet_user.sh,接收用户名作为参数,输出"Hello, 用户名"。
  2. 编写一个 for 循环,创建 10 个文件:file1.txt ~ file10.txt
  3. 编写一个 while 循环,持续检查 nginx 服务状态,每 5 秒一次。
  4. 创建一个函数 create_user,接收用户名参数,自动创建用户并设置密码。
  5. 修改监控脚本,增加对 CPU 使用率的检查。
  6. (挑战)编写一个备份脚本,只在工作日(周一到周五)执行。

🔜 下一章预告:第19章《openEuler 中的容器支持(Docker 与 iSulad)》

我们将学习:

  • 什么是容器?Docker 与 iSulad 的区别
  • openEuler 默认容器引擎:iSulad 架构与优势
  • 安装与配置 iSulad
  • 镜像管理:pull、tag、push
  • 容器生命周期:run、start、stop、rm
  • 实战:在 openEuler 上运行 Nginx 容器

准备好进入云原生时代了吗?

相关推荐
yanlaifan17 小时前
Shell编程---shell bash中的keyword
shell
柒号华仔1 天前
「速通Shell」常用命令(下)—— 归档、权限与进阶工具
shell
柒号华仔2 天前
「速通Shell」常用命令(中)——进程、网络与系统信息
shell
YuSun_WK3 天前
shell脚本
shell·脚本
柒号华仔6 天前
「速通Shell」Shell 脚本测试详解
shell
柒号华仔7 天前
「速通Shell」Shell 脚本模块化
shell
柒号华仔8 天前
「速通Shell」Shell编程的错误处理与日志
shell
柒号华仔9 天前
「速通Shell」Shell 数组、关联数组与 mapfile
shell
苏灿烤鱼11 天前
一套进程代替八件套,桌面更稳还是单点更大
linux·github·shell
茶本无香11 天前
通用报表自动化框架:Java调用Shell传参执行PostgreSQL SQL模板
java·sql·postgresql·shell