前言
在 Linux 系统管理与自动化运维领域,Shell 脚本是不可或缺的核心工具。它能够将复杂的运维操作抽象为可执行的代码序列,通过逻辑判断实现 “自动化决策”,极大提升了工作效率。而条件测试与分支语句,正是 Shell 脚本实现逻辑控制的基石 —— 它们如同脚本的 “大脑”,让程序能够根据不同的条件执行差异化的操作。
无论是验证文件是否存在、判断用户权限,还是根据输入参数执行不同业务逻辑,亦或是编写服务启停脚本、自动化部署程序,都离不开条件测试与分支语句的支撑。本文基于实战视角,以 CentOS 系统为环境,全面拆解 Shell 中条件测试的核心语法,深入讲解if单分支、双分支、多分支语句的结构与应用,同时剖析case分支语句的适用场景与实战技巧。
本文内容严格贴合企业运维实战需求,所有案例均经过实际验证,代码可直接复用。无论是 Linux 运维新手、脚本开发入门者,还是希望提升 Shell 编程能力的资深工程师,都能通过本文掌握条件语句的核心用法,为编写健壮、高效的 Shell 脚本奠定坚实基础。
一、条件测试操作:Shell 脚本的 “判断基石”
在 Shell 编程中,条件测试是指通过特定的命令或语法,判断某个条件是否成立。条件成立时,测试结果返回0(在 Shell 中,0 代表真 / 成功);条件不成立时,返回非 0 值(通常为 1,代表假 / 失败)。
条件测试的结果是分支语句执行的依据,其测试范围覆盖文件属性、数值比较、字符串比较三大核心场景,同时支持复合条件测试实现多条件联合判断。
1.1 条件测试的两种语法格式
Shell 中执行条件测试,主要有两种标准格式,二者功能完全等价,可根据编程习惯灵活选择:
格式一:使用test命令
test 条件表达式
格式二:使用方括号(推荐)
[ 条件表达式 ]
核心注意事项:方括号
[ ]与条件表达式之间必须保留空格,这是 Shell 语法的强制要求。若缺少空格,Shell 会将[条件表达式]识别为一个整体命令,导致语法错误。
执行条件测试后,可通过 Shell 内置变量$?获取测试结果(echo $?):返回 0 表示条件成立,返回非 0 表示条件不成立。
1.2 文件属性测试:判断文件系统对象的状态
文件属性测试是运维脚本中最常用的测试类型,用于验证文件 / 目录的存在性、类型、权限等属性。核心测试选项如下表所示:
表格
| 测试选项 | 功能描述 | 适用场景 |
|---|---|---|
-d 路径 | 判断指定路径是否为目录 | 验证目录是否存在,避免创建目录时冲突 |
-f 路径 | 判断指定路径是否为普通文件 | 验证配置文件、脚本文件是否存在 |
-e 路径 | 判断指定路径是否存在(文件 / 目录均可) | 通用的存在性验证 |
-r 路径 | 判断当前用户是否拥有读权限 | 验证脚本是否能读取目标文件 |
-w 路径 | 判断当前用户是否拥有写权限 | 验证脚本是否能写入目标文件 |
-x 路径 | 判断当前用户是否拥有执行权限 | 验证脚本、命令是否可执行 |
-s 路径 | 判断文件是否为非空文件 | 验证日志文件、数据文件是否有内容 |
实战案例 1:验证目录是否存在
在自动化部署脚本中,常需先验证目标目录是否存在,不存在则创建。
# 测试/media/cdrom目录是否为目录
[root@localhost ~]# [ -d /media/cdrom ]
# 查看测试结果(0表示存在,1表示不存在)
[root@localhost ~]# echo $?
0
# 实战脚本片段:不存在则创建目录
#!/bin/bash
if [ ! -d /media/cdrom ]; then
mkdir -p /media/cdrom
echo "目录/media/cdrom创建成功"
fi
实战案例 2:验证文件是否可执行
在执行自定义脚本前,验证其是否拥有执行权限,避免 “Permission denied” 错误。
# 测试/root/chenmoinit.sh是否可执行
[root@localhost ~]# [ -x /root/chenmoinit.sh ]
[root@localhost ~]# echo $?
1 # 表示无执行权限
# 赋予执行权限后重新测试
[root@localhost ~]# chmod +x /root/chenmoinit.sh
[root@localhost ~]# [ -x /root/chenmoinit.sh ]
[root@localhost ~]# echo $?
0
1.3 数值比较:判断数字的大小关系
数值比较用于对整数进行大小、相等性判断,不支持浮点数。核心测试选项如下表所示(注意:整数1与整数2均为整数,不可包含小数、字母):
表格
| 测试选项 | 功能描述 | 示例 |
|---|---|---|
-eq | 等于(Equal) | [ 10 -eq 10 ](成立) |
-ne | 不等于(Not Equal) | [ 10 -ne 5 ](成立) |
-gt | 大于(Greater Than) | [ 10 -gt 5 ](成立) |
-lt | 小于(Less Than) | [ 5 -lt 10 ](成立) |
-ge | 大于等于(Greater or Equal) | [ 10 -ge 10 ](成立) |
-le | 小于等于(Lesser or Equal) | [ 5 -le 10 ](成立) |
实战案例 1:验证数值是否相等
判断系统当前负载、进程数量等数值是否符合预期,例如验证两个变量的值是否相等。
# 定义两个整数变量
[root@localhost ~]# num1=10
[root@localhost ~]# num2=10
# 测试num1是否等于num2
[root@localhost ~]# [ $num1 -eq $num2 ]
[root@localhost ~]# echo $?
0
# 测试num1是否大于num2
[root@localhost ~]# [ $num1 -gt $num2 ]
[root@localhost ~]# echo $?
1
实战案例 2:验证磁盘使用率是否超标
编写脚本监控根目录磁盘使用率,若使用率超过 80%,则输出告警信息。
#!/bin/bash
# 获取根目录磁盘使用率(提取整数部分)
USE_RATE=$(df -h / | grep / | awk '{print $5}' | sed 's/%//g')
# 测试使用率是否大于80
if [ $USE_RATE -gt 80 ]; then
echo "告警:根目录磁盘使用率已达到${USE_RATE}%,请及时清理!"
fi
1.4 字符串比较:判断文本的匹配与状态
字符串比较用于验证文本的相等性、空值、大小关系,常用于处理用户输入、配置项验证、参数判断等场景。核心测试选项与语法如下:
表格
| 测试场景 | 测试语法 | 功能描述 |
|---|---|---|
| 相等性判断 | [ 字符串1 = 字符串2 ] | 字符串 1 与字符串 2 完全一致则成立(等号两侧需空格) |
| 不等性判断 | [ 字符串1 != 字符串2 ] | 字符串 1 与字符串 2 不一致则成立 |
| 空值判断 | [ -z 字符串 ] | 字符串长度为 0(空字符串)则成立 |
| 非空判断 | [ -n 字符串 ] | 字符串长度非 0(非空)则成立 |
注意:字符串比较的
=和!=两侧必须保留空格;若比较的字符串包含空格,需用双引号""包裹,避免 Shell 解析错误。
实战案例 1:验证用户输入是否为 “yes”
在脚本中获取用户确认时,常需判断用户输入是否为指定字符串。
# 测试字符串是否为"yes"
[root@localhost ~]# [ "yes" = "yes" ]
[root@localhost ~]# echo $?
0
# 测试字符串是否为"no"
[root@localhost ~]# [ "yes" != "no" ]
[root@localhost ~]# echo $?
0
# 实战脚本:获取用户确认后执行操作
#!/bin/bash
read -p "是否确认执行安装操作(yes/no):" INPUT
if [ $INPUT = "yes" ]; then
echo "开始执行安装..."
# 此处可添加实际安装命令
else
echo "用户取消安装操作"
fi
实战案例 2:验证脚本参数是否为空
编写脚本时,常需验证用户是否传入了必要的参数,若未传入则提示用法并退出。
#!/bin/bash
# 验证第一个参数是否为空
if [ -z $1 ]; then
echo "用法:$0 <目标IP地址>"
exit 1 # 非0退出表示脚本执行失败
fi
echo "目标IP地址为:$1"
1.5 复合条件测试:多条件联合判断
在实际场景中,往往需要同时满足多个条件,或满足其中一个条件即可执行操作,这就需要使用复合条件测试。Shell 通过逻辑运算符实现多条件联合判断,核心运算符如下:
表格
| 逻辑关系 | 测试语法 | 功能描述 | 短路特性 |
|---|---|---|---|
| 逻辑与 | [ 条件1 ] && [ 条件2 ] | 条件 1 与条件 2同时成立则整体成立 | 条件 1 不成立时,直接跳过条件 2 |
| 逻辑或 | [ 条件1 ] || [ 条件2 ] | 条件 1 与条件 2有一个成立则整体成立 | 条件 1 成立时,直接跳过条件 2 |
| 逻辑非 | [ ! 条件 ] | 原条件不成立时,整体成立 | - |
注意:在 Shell 脚本中,
&&和||是特殊字符,若在[ ]内部使用,需加反斜杠转义(\&&、\|\|);推荐使用外部连接的方式([ 条件1 ] && [ 条件2 ]),更符合编程习惯。
实战案例 1:逻辑与 —— 验证文件存在且可读写
判断/etc/passwd是否存在,且当前用户拥有读、写权限。
#!/bin/bash
FILE="/etc/passwd"
if [ -e $FILE ] && [ -r $FILE ] && [ -w $FILE ]; then
echo "$FILE 存在,且当前用户拥有读写权限"
else
echo "$FILE 不存在,或当前用户权限不足"
fi
实战案例 2:逻辑或 —— 验证进程是否运行
判断nginx或apache进程是否正在运行,若都未运行则输出告警。
#!/bin/bash
NGINX_PID=$(ps -ef | grep nginx | grep -v grep | wc -l)
APACHE_PID=$(ps -ef | grep httpd | grep -v grep | wc -l)
if [ $NGINX_PID -eq 0 ] && [ $APACHE_PID -eq 0 ]; then
echo "告警:Web服务(nginx/apache)均未运行!"
fi
实战案例 3:逻辑非 —— 验证用户是否为 root
编写脚本时,常需限制仅 root 用户可执行,若为普通用户则提示并退出。
#!/bin/bash
# 验证当前用户是否为root($USER为环境变量,存储当前用户名)
if [ ! $USER = "root" ]; then
echo "错误:非root用户,权限不足!"
exit 1
fi
echo "当前为root用户,开始执行脚本..."
二、if 分支语句:Shell 的 “多场景决策引擎”
if语句是 Shell 中最常用的分支语句,根据条件测试的结果,执行不同的命令序列。其核心逻辑是 “如果…… 那么……”,支持单分支、双分支、多分支三种结构,分别适配不同的业务复杂度。
2.1 if 语句的核心语法规则
if语句以if开头,以fi结尾(fi是if的倒序),必须成对出现;- 条件测试部分可使用
test命令、[ ],也可直接使用命令的执行结果(命令返回 0 则条件成立); - 命令序列部分由一条或多条 Shell 命令组成,必须缩进(推荐 4 个空格),提升代码可读性;
then关键字可与if同行(需用分号;分隔),也可单独换行。
2.2 单分支 if 语句:满足条件则执行,否则跳过
2.2.1 语法结构
单分支if语句适用于 “条件成立则执行,不成立则无操作” 的场景,是最基础的分支结构。
# 格式1:then与if同行
if [ 条件表达式 ]; then
命令序列
fi
# 格式2:then单独换行(推荐)
if [ 条件表达式 ]
then
命令序列
fi
2.2.2 实战案例 1:自动挂载光盘目录
在 Linux 系统中,若/media/cdrom目录不存在,则创建该目录;若已存在,则挂载光盘设备。
#!/bin/bash
# 定义挂载目录和设备
MOUNT_DIR="/media/cdrom"
DEVICE="/dev/sr0"
# 单分支1:判断挂载目录是否存在,不存在则创建
if [ ! -d $MOUNT_DIR ]
then
mkdir -p $MOUNT_DIR
echo "挂载目录${MOUNT_DIR}创建成功"
fi
# 单分支2:判断是否已挂载,未挂载则执行挂载
if [ ! -mount $MOUNT_DIR ]
then
mount $DEVICE $MOUNT_DIR
echo "光盘已成功挂载至${MOUNT_DIR}"
fi
2.2.3 实战案例 2:清理旧日志文件
编写脚本,清理 7 天前的 Nginx 日志文件,避免日志文件占用过多磁盘空间。
#!/bin/bash
# 定义日志目录
LOG_DIR="/var/log/nginx"
# 判断日志目录是否存在,存在则清理旧日志
if [ -d $LOG_DIR ]
then
find $LOG_DIR -name "*.log" -mtime +7 -delete
echo "已清理${LOG_DIR}下7天前的日志文件"
fi
2.3 双分支 if 语句:二选一的条件执行
2.3.1 语法结构
双分支if语句适用于 “条件成立执行命令序列 1,不成立执行命令序列 2” 的二选一场景。
if [ 条件表达式 ]
then
命令序列1 # 条件成立时执行
else
命令序列2 # 条件不成立时执行
fi
2.3.2 实战案例 1:判断主机是否在线
编写脚本,检测指定 IP 地址的主机是否在线,在线则输出 “UP”,不在线则输出 “DOWN”。
#!/bin/bash
# 获取用户输入的IP地址
read -p "请输入要检测的IP地址:" IP
# 执行ping测试(-c 3:发送3个数据包;-i 0.2:间隔0.2秒;-W 3:超时3秒)
ping -c 3 -i 0.2 -W 3 $IP &>/dev/null
# 双分支判断:根据ping命令的返回值(0为在线,非0为不在线)
if [ $? -eq 0 ]
then
echo "Host $IP is up."
else
echo "Host $IP is down."
fi
2.3.3 实战案例 2:管理服务启停状态
编写脚本,判断vsftpd服务是否运行,运行则停止,未运行则启动。
#!/bin/bash
# 定义服务名称
SERVICE="vsftpd"
# 获取服务状态(&>/dev/null 屏蔽无关输出)
systemctl status $SERVICE &>/dev/null
# 双分支判断服务状态
if [ $? -eq 0 ]
then
echo "当前${SERVICE}服务正在运行,准备停止..."
systemctl stop $SERVICE
echo "${SERVICE}服务已停止"
else
echo "当前${SERVICE}服务未运行,准备启动..."
systemctl start $SERVICE
echo "${SERVICE}服务已启动"
fi
2.4 多分支 if 语句:多条件的差异化执行
2.4.1 语法结构
多分支if语句适用于 “存在多个条件,满足不同条件执行不同命令序列” 的场景,通过elif(else if 的缩写)实现多条件判断。
if [ 条件表达式1 ]
then
命令序列1 # 条件1成立时执行
elif [ 条件表达式2 ]
then
命令序列2 # 条件2成立时执行
elif [ 条件表达式3 ]
then
命令序列3 # 条件3成立时执行
...
else
命令序列n # 所有条件均不成立时执行
fi
核心逻辑:多分支
if语句按顺序判断条件,一旦某个条件成立,执行对应的命令序列后,直接退出if语句,后续条件不再判断。
2.4.2 实战案例 1:成绩等级判定
编写脚本,根据用户输入的考试成绩(0-100),判定成绩等级:90 分及以上为 “优秀”,70-89 分为 “合格”,70 分以下为 “不合格”。
#!/bin/bash
# 获取用户输入的成绩,并验证是否为整数
read -p "请输入考试成绩(0-100):" GRADE
# 第一步:验证输入是否为有效整数(0-100)
if ! [[ $GRADE =~ ^[0-9]+$ ]] || [ $GRADE -lt 0 ] || [ $GRADE -gt 100 ]
then
echo "输入错误:请输入0-100之间的整数!"
exit 1
fi
# 第二步:多分支判定成绩等级
if [ $GRADE -ge 90 ]
then
echo "${GRADE}分,优秀!"
elif [ $GRADE -ge 70 ]
then
echo "${GRADE}分,合格!"
else
echo "${GRADE}分,不合格!"
fi
2.4.3 实战案例 2:根据系统位数安装软件
编写脚本,检测系统的架构(32 位 / 64 位),并根据架构下载对应的软件包。
#!/bin/bash
# 获取系统架构(uname -m:返回硬件架构)
ARCH=$(uname -m)
# 多分支判断系统架构
if [ $ARCH = "i386" ] || [ $ARCH = "i686" ]
then
echo "检测到32位系统,准备下载32位软件包..."
# 此处添加32位软件包下载命令
wget https://example.com/software-32bit.tar.gz -O /tmp/software.tar.gz
elif [ $ARCH = "x86_64" ]
then
echo "检测到64位系统,准备下载64位软件包..."
# 此处添加64位软件包下载命令
wget https://example.com/software-64bit.tar.gz -O /tmp/software.tar.gz
else
echo "不支持的系统架构:$ARCH"
exit 1
fi
三、case 分支语句:Shell 的 “固定值匹配神器”
case语句是另一种核心分支语句,适用于 “变量为固定的离散值,根据不同值执行不同命令序列” 的场景。与if多分支语句相比,case语句在处理固定值匹配时,代码更简洁、可读性更强,尤其适合编写菜单脚本、服务启停脚本、参数解析脚本。
3.1 case 语句的核心语法结构
case 变量名 in
模式1)
命令序列1
;; # 结束当前模式(双分号,必须添加)
模式2)
命令序列2
;;
模式3)
命令序列3
;;
*) # 通配模式,匹配所有未定义的模式(可选)
命令序列n
;;
esac # case的倒序,必须成对出现
3.2 case 语句的核心匹配规则
- 变量与模式匹配:
case会将变量名的值依次与模式1、模式2…… 进行匹配,按顺序匹配,一旦匹配成功,执行对应的命令序列,然后通过;;退出case语句; - 模式支持通配符:
- 精确匹配:直接写固定值(如
1、start、yes); - 范围匹配:使用
[ ]匹配单个字符(如[0-9]、[a-z]); - 通配匹配:使用
*匹配任意字符,?匹配单个字符;
- 精确匹配:直接写固定值(如
- 通配模式
*:若所有模式均未匹配成功,执行*)后的命令序列(类似if语句的else); - 结束符要求:每个模式的命令序列必须以
;;结尾,case语句整体以esac结尾。
3.3 实战案例 1:判断输入字符的类型
编写脚本,接收用户输入的一个字符,判断其是否为字母、数字,或其他字符(空格、符号等)。
#!/bin/bash
# 获取用户输入的一个字符
read -p "请输入一个字符,并按Enter键确认:" KEY
# case语句判断字符类型
case $KEY in
[a-z]|[A-Z]) # 匹配大小写字母
echo "您输入的是字母。"
;;
[0-9]) # 匹配数字
echo "您输入的是数字。"
;;
*) # 匹配其他字符
echo "您输入的是空格、功能键或其他特殊字符。"
;;
esac
3.4 实战案例 2:编写服务管理菜单脚本
模拟系统systemctl命令,编写nginx服务的管理脚本,支持start、stop、restart、status四种操作,输入其他指令则提示用法。
#!/bin/bash
# 定义服务名称
SERVICE="nginx"
# 提示用户输入操作指令
echo "===== Nginx服务管理菜单 ====="
echo "1. start:启动服务"
echo "2. stop:停止服务"
echo "3. restart:重启服务"
echo "4. status:查看状态"
echo "============================"
read -p "请输入操作指令(1-4):" OPT
# case语句处理用户输入
case $OPT in
1|start) # 支持数字1或字符串start
systemctl start $SERVICE
echo "Nginx服务已启动"
;;
2|stop)
systemctl stop $SERVICE
echo "Nginx服务已停止"
;;
3|restart)
systemctl restart $SERVICE
echo "Nginx服务已重启"
;;
4|status)
systemctl status $SERVICE
;;
*)
echo "用法:$0 {start|stop|restart|status} 或 输入数字1-4"
exit 1
;;
esac
3.5 实战案例 3:解析脚本启动参数
编写自动化部署脚本,通过启动参数指定部署环境(dev/test/prod),根据不同环境加载不同的配置文件。
#!/bin/bash
# 验证是否传入部署环境参数
if [ -z $1 ]
then
echo "错误:未指定部署环境!"
echo "用法:$0 {dev|test|prod}"
exit 1
fi
# case语句匹配部署环境
case $1 in
dev)
CONFIG_FILE="/etc/app/dev.conf"
echo "开始部署【开发环境】,加载配置文件:$CONFIG_FILE"
;;
test)
CONFIG_FILE="/etc/app/test.conf"
echo "开始部署【测试环境】,加载配置文件:$CONFIG_FILE"
;;
prod)
CONFIG_FILE="/etc/app/prod.conf"
echo "开始部署【生产环境】,加载配置文件:$CONFIG_FILE"
;;
*)
echo "错误:不支持的部署环境!"
echo "支持的环境:dev、test、prod"
exit 1
;;
esac
# 模拟部署命令
echo "正在执行部署脚本,使用配置:$CONFIG_FILE"
# sh deploy.sh $CONFIG_FILE
四、if 与 case 语句的选型指南
在 Shell 编程中,if和case语句均可实现分支逻辑,但二者的适用场景存在明显差异,合理选型能让代码更高效、更易维护。
表格
| 选型维度 | 推荐使用if语句 | 推荐使用case语句 |
|---|---|---|
| 条件类型 | 数值比较、字符串模糊判断、复合条件、命令执行结果判断 | 变量的固定离散值匹配、菜单选项、参数解析 |
| 条件数量 | 少量条件(≤3 个)或条件复杂 | 大量固定值(≥3 个)或值类型统一 |
| 匹配规则 | 支持大小、范围、逻辑组合等复杂判断 | 支持精确匹配、通配符匹配,不支持复杂逻辑 |
| 代码可读性 | 条件简单时可读性强,条件复杂时易冗余 | 固定值匹配时,代码结构清晰,易扩展 |
核心总结:
- 若需判断数值大小、文件属性、复合条件,或依赖命令执行结果,优先使用
if语句; - 若需处理菜单选择、服务启停参数、固定环境匹配等场景,优先使用
case语句。
五、实战综合案例:企业级自动化运维脚本
结合本文所学的条件测试、if与case语句,编写一个企业级服务器初始化脚本,实现以下功能:
- 验证执行用户是否为 root;
- 支持选择初始化类型(基础初始化 / 应用初始化 / 安全初始化);
- 基础初始化:关闭防火墙、关闭 SELinux、配置 YUM 源;
- 应用初始化:安装常用工具(vim、wget、net-tools)、安装 Docker;
- 安全初始化:设置 root 密码、禁止 root 远程登录、创建普通用户并赋予 sudo 权限;
- 支持取消操作,输入错误则提示用法。
5.1 脚本完整代码
#!/bin/bash
# 脚本名称:server_init.sh
# 功能:企业级服务器初始化脚本
# 作者:CSDN运维实战
# 日期:2026-02-25
# 定义颜色变量(提升输出可读性)
RED="\033[31m"
GREEN="\033[32m"
YELLOW="\033[33m"
RESET="\033[0m"
# 函数:输出信息
info() {
echo -e "${GREEN}[INFO] $1${RESET}"
}
# 函数:输出警告
warn() {
echo -e "${YELLOW}[WARN] $1${RESET}"
}
# 函数:输出错误
error() {
echo -e "${RED}[ERROR] $1${RESET}"
exit 1
}
# 第一步:验证执行用户是否为root
if [ ! $USER = "root" ]; then
error "脚本必须以root用户执行!"
fi
# 第二步:显示初始化菜单
show_menu() {
clear
echo "==================== 服务器初始化菜单 ===================="
echo "1. 基础初始化(关闭防火墙/SELinux、配置YUM源)"
echo "2. 应用初始化(安装常用工具、Docker)"
echo "3. 安全初始化(设置密码、禁止root远程、创建用户)"
echo "4. 全量初始化(执行1+2+3)"
echo "5. 取消操作"
echo "=========================================================="
read -p "请输入您的选择(1-5):" CHOICE
}
# 第三步:定义各初始化函数
# 3.1 基础初始化
basic_init() {
info "开始执行基础初始化..."
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
info "防火墙已关闭并禁用"
# 关闭SELinux
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
info "SELinux已临时关闭,永久生效需重启服务器"
# 配置阿里YUM源(以CentOS 7为例)
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all
yum makecache
info "阿里YUM源配置完成"
info "基础初始化执行完毕!"
}
# 3.2 应用初始化
app_init() {
info "开始执行应用初始化..."
# 安装常用工具
yum install -y vim wget net-tools tree
info "常用工具安装完成"
# 安装Docker
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
systemctl start docker
systemctl enable docker
info "Docker安装完成并启动"
info "应用初始化执行完毕!"
}
# 3.3 安全初始化
security_init() {
info "开始执行安全初始化..."
# 设置root密码
read -s -p "请设置root新密码:" ROOT_PASS
echo
echo "root:$ROOT_PASS" | chpasswd
info "root密码已修改"
# 禁止root远程登录
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart sshd
info "已禁止root用户远程登录"
# 创建普通用户并赋予sudo权限
read -p "请输入要创建的普通用户名:" USER_NAME
useradd $USER_NAME
read -s -p "请设置${USER_NAME}的密码:" USER_PASS
echo
echo "${USER_NAME}:${USER_PASS}" | chpasswd
usermod -aG wheel $USER_NAME
info "普通用户${USER_NAME}创建完成,已赋予sudo权限"
info "安全初始化执行完毕!"
}
# 第四步:主逻辑(case语句处理用户选择)
show_menu
case $CHOICE in
1)
basic_init
;;
2)
app_init
;;
3)
security_init
;;
4)
basic_init
app_init
security_init
info "全量初始化执行完毕!"
;;
5)
warn "用户取消操作,脚本退出"
exit 0
;;
*)
error "输入错误:请输入1-5之间的数字!"
;;
esac
info "服务器初始化脚本执行完成!"
5.2 脚本执行说明
- 赋予脚本执行权限:
chmod +x server_init.sh; - 执行脚本:
./server_init.sh; - 按照菜单提示选择初始化类型,根据指引完成操作。
该脚本整合了本文所有核心知识点,充分体现了条件测试、if语句、case语句在企业实战中的应用,代码结构清晰、注释完善,可直接根据实际需求修改后投入生产使用。
六、总结与进阶建议
6.1 核心知识点总结
本文围绕 Shell 编程的条件测试与分支语句展开,核心要点如下:
- 条件测试是分支语句的基础,分为文件属性、数值比较、字符串比较、复合条件四大类,掌握
[ ]的用法是核心; - if 语句支持单分支、双分支、多分支,适配复杂的条件判断场景,是 Shell 编程的 “万能决策工具”;
- case 语句专注于固定值匹配,在菜单脚本、参数解析中优势明显,代码可读性更高;
- 实际开发中,需根据业务场景合理选择
if或case语句,结合函数封装,提升代码的可维护性。
6.2 进阶学习建议
- 掌握高级条件测试:学习
[[ ]](支持正则表达式匹配)和(( ))(专门用于数值运算与比较),弥补[ ]的不足; - 学习循环语句:结合
for、while、until循环语句,实现批量操作(如批量创建用户、批量检测主机); - 脚本健壮性优化:添加参数校验、异常处理、日志记录,让脚本能够应对各种异常场景;
- 实战项目积累:编写自动化部署脚本、监控脚本、备份脚本,将理论知识转化为实战能力。
Shell 编程的核心在于 “实战”,只有不断编写脚本、解决实际问题,才能真正掌握其精髓。希望本文能成为你 Shell 编程之路的重要基石,后续将持续分享更多 Shell 进阶实战内容,敬请关注!

1128

被折叠的 条评论
为什么被折叠?



