恭喜你已经掌握了 Linux 系统管理的核心技能。现在,是时候将这些命令"串联"起来,通过 Shell 脚本 实现自动化,大幅提升运维效率。在 openEuler 环境中,Bash 脚本是自动化任务、系统维护、部署流程的基石。本章将带你从零开始,写出第一个"会思考"的脚本。
🌟 本章目标
- 理解 Shell 脚本的作用与执行方式
- 掌握脚本结构:
#!/bin/bash与权限设置 - 学会定义和使用变量(普通变量、环境变量、位置参数)
- 使用
if语句进行条件判断(文件、字符串、数字) - 使用
for、while循环批量处理任务 - 定义和调用函数,提高代码复用性
- 实战:编写一个系统资源监控与告警脚本
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,需显式调用解释器:
bashbash 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 循环:for 与 while
🔁 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, $?, $@ |
脚本元信息 |
📝 课后练习
- 编写一个脚本
greet_user.sh,接收用户名作为参数,输出"Hello, 用户名"。 - 编写一个
for循环,创建 10 个文件:file1.txt~file10.txt。 - 编写一个
while循环,持续检查nginx服务状态,每 5 秒一次。 - 创建一个函数
create_user,接收用户名参数,自动创建用户并设置密码。 - 修改监控脚本,增加对 CPU 使用率的检查。
- (挑战)编写一个备份脚本,只在工作日(周一到周五)执行。
🔜 下一章预告:第19章《openEuler 中的容器支持(Docker 与 iSulad)》
我们将学习:
- 什么是容器?Docker 与 iSulad 的区别
- openEuler 默认容器引擎:iSulad 架构与优势
- 安装与配置 iSulad
- 镜像管理:pull、tag、push
- 容器生命周期:run、start、stop、rm
- 实战:在 openEuler 上运行 Nginx 容器
准备好进入云原生时代了吗?