Shell 编程核心实战:条件测试与分支语句全解析

前言

在 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:逻辑或 —— 验证进程是否运行

判断nginxapache进程是否正在运行,若都未运行则输出告警。

#!/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 语句的核心语法规则

  1. if语句以if开头,以fi结尾(fiif的倒序),必须成对出现
  2. 条件测试部分可使用test命令、[ ],也可直接使用命令的执行结果(命令返回 0 则条件成立);
  3. 命令序列部分由一条或多条 Shell 命令组成,必须缩进(推荐 4 个空格),提升代码可读性;
  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 语句的核心匹配规则

  1. 变量与模式匹配case会将变量名的值依次与模式1模式2…… 进行匹配,按顺序匹配,一旦匹配成功,执行对应的命令序列,然后通过;;退出case语句;
  2. 模式支持通配符
    • 精确匹配:直接写固定值(如1startyes);
    • 范围匹配:使用[ ]匹配单个字符(如[0-9][a-z]);
    • 通配匹配:使用*匹配任意字符,?匹配单个字符;
  3. 通配模式*:若所有模式均未匹配成功,执行*)后的命令序列(类似if语句的else);
  4. 结束符要求:每个模式的命令序列必须以;;结尾,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服务的管理脚本,支持startstoprestartstatus四种操作,输入其他指令则提示用法。

#!/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 编程中,ifcase语句均可实现分支逻辑,但二者的适用场景存在明显差异,合理选型能让代码更高效、更易维护。

表格

选型维度推荐使用if语句推荐使用case语句
条件类型数值比较、字符串模糊判断、复合条件、命令执行结果判断变量的固定离散值匹配、菜单选项、参数解析
条件数量少量条件(≤3 个)或条件复杂大量固定值(≥3 个)或值类型统一
匹配规则支持大小、范围、逻辑组合等复杂判断支持精确匹配、通配符匹配,不支持复杂逻辑
代码可读性条件简单时可读性强,条件复杂时易冗余固定值匹配时,代码结构清晰,易扩展

核心总结

  • 若需判断数值大小文件属性复合条件,或依赖命令执行结果,优先使用if语句;
  • 若需处理菜单选择服务启停参数固定环境匹配等场景,优先使用case语句。

五、实战综合案例:企业级自动化运维脚本

结合本文所学的条件测试、ifcase语句,编写一个企业级服务器初始化脚本,实现以下功能:

  1. 验证执行用户是否为 root;
  2. 支持选择初始化类型(基础初始化 / 应用初始化 / 安全初始化);
  3. 基础初始化:关闭防火墙、关闭 SELinux、配置 YUM 源;
  4. 应用初始化:安装常用工具(vim、wget、net-tools)、安装 Docker;
  5. 安全初始化:设置 root 密码、禁止 root 远程登录、创建普通用户并赋予 sudo 权限;
  6. 支持取消操作,输入错误则提示用法。

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 脚本执行说明

  1. 赋予脚本执行权限:chmod +x server_init.sh
  2. 执行脚本:./server_init.sh
  3. 按照菜单提示选择初始化类型,根据指引完成操作。

该脚本整合了本文所有核心知识点,充分体现了条件测试、if语句、case语句在企业实战中的应用,代码结构清晰、注释完善,可直接根据实际需求修改后投入生产使用。

六、总结与进阶建议

6.1 核心知识点总结

本文围绕 Shell 编程的条件测试分支语句展开,核心要点如下:

  1. 条件测试是分支语句的基础,分为文件属性、数值比较、字符串比较、复合条件四大类,掌握[ ]的用法是核心;
  2. if 语句支持单分支、双分支、多分支,适配复杂的条件判断场景,是 Shell 编程的 “万能决策工具”;
  3. case 语句专注于固定值匹配,在菜单脚本、参数解析中优势明显,代码可读性更高;
  4. 实际开发中,需根据业务场景合理选择ifcase语句,结合函数封装,提升代码的可维护性。

6.2 进阶学习建议

  1. 掌握高级条件测试:学习[[ ]](支持正则表达式匹配)和(( ))(专门用于数值运算与比较),弥补[ ]的不足;
  2. 学习循环语句:结合forwhileuntil循环语句,实现批量操作(如批量创建用户、批量检测主机);
  3. 脚本健壮性优化:添加参数校验、异常处理、日志记录,让脚本能够应对各种异常场景;
  4. 实战项目积累:编写自动化部署脚本、监控脚本、备份脚本,将理论知识转化为实战能力。

Shell 编程的核心在于 “实战”,只有不断编写脚本、解决实际问题,才能真正掌握其精髓。希望本文能成为你 Shell 编程之路的重要基石,后续将持续分享更多 Shell 进阶实战内容,敬请关注!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值