简介
想象一下,你正在使用 GPS 驾驶汽车。GPS 不会只提供一份固定的指令列表,而是会根据道路情况做出反应。如果遇到拥堵,它会为你重新规划路线;如果你错过了转弯,它会重新计算路线。
在脚本中,这称为条件逻辑。没有条件逻辑,脚本就只是一串盲目执行的命令。有了条件逻辑,脚本可以检查当前情况,并选择下一步要执行的操作。
这是构建可靠自动化的基础之一。真实系统的状态并不总是相同,因此优秀的脚本必须能够做出反应,而不能想当然地假设环境始终不变。
在本实验中,你将使用 if 和 else 为脚本添加一个「大脑」。
你将让脚本学会:
- 检查实际情况:在尝试打开文件之前,先检查文件是否确实存在。
- 做出决策:如果答案是「是」,执行一种操作;如果答案是「否」,执行另一种操作。
- 检查身份:验证用户是否具有运行脚本所需的权限(Root)。
检查文件是否存在
优秀的脚本就像谨慎的驾驶员:行动前会先观察。在 Linux 中,最常见的检查之一就是:「这个文件是否存在?」
我们会在 if 代码块中使用 -f 标志(文件检查)。可以把 if 想象成一名门卫:只有满足条件时,它才允许代码块中的内容继续执行。
这是脚本根据系统状态做出决策的第一个实际示例。脚本由「按顺序运行命令」进步到「检查环境,然后选择操作」,这是一个重要转变。许多系统管理脚本正是建立在这种模式之上。
先进入项目目录:
cd ~/project
创建名为 check_file.sh 的新脚本:
nano check_file.sh
输入以下代码。我们将检查 data.txt 是否存在。
#!/bin/bash
FILE="data.txt"
if [ -f "$FILE" ]; then
echo "$FILE exists."
fi
解析这段逻辑:
if [ ... ]; then:这是门卫。它会检查方括号中的条件。-f "$FILE":要检查的问题是:「data.txt是一个实际存在的文件吗?」echo ...:这是要执行的操作。只有门卫的回答为「是」时,这条命令才会执行。fi:「Finish If」的缩写,表示条件代码块到此结束。
[ ... ] 这种方括号形式是 Bash 中执行测试的常用写法。这里检查的是文件属性。Linux 和 Bash 提供了许多这样的测试运算符,掌握它们后,脚本就可以判断文件、字符串、数字和权限。
保存(Ctrl+O)并退出(Ctrl+X)。
为脚本添加可执行权限:
chmod +x check_file.sh
测试 1:文件不存在
现在运行脚本:
./check_file.sh
不会发生任何事情。 终端没有输出。
原因是 data.txt 不存在。门卫的回答是「否」,因此完全跳过了 echo 命令。
测试 2:文件存在
现在创建该文件:
touch data.txt
再次运行脚本:
./check_file.sh
这次门卫的回答是「是」,你会看到:
data.txt exists.
添加 Else 代码块
没有输出会让人困惑。如果脚本什么都不做,你无法判断它是执行失败了,还是已经正常结束。我们需要一个备用方案。
在逻辑上,这就是「道路分叉」。
- 路径 A(if):文件存在。很好。
- 路径 B(else):文件缺失。我们来修复它。
修改脚本,让它自动创建缺失的文件。
先删除测试文件,以便执行一次真正的测试:
rm data.txt
打开脚本:
nano check_file.sh
按下面的示例添加 else 代码块:
#!/bin/bash
FILE="data.txt"
if [ -f "$FILE" ]; then
echo "$FILE exists."
else
echo "$FILE does not exist. Creating it now..."
touch "$FILE"
fi
这段逻辑:
如果 if 条件为真,就执行第一部分。
如果 if 条件为假,就执行 else 部分。
与只输出信息的脚本相比,这类脚本通常更接近实际运维工作。它不只是报告文件缺失,还会自动修复问题。这正是条件逻辑成为许多初始化和维护脚本基础的原因。
保存并退出。
测试这段逻辑
运行脚本。由于 data.txt 不存在,脚本应该执行路径 B:
./check_file.sh
输出:
data.txt does not exist. Creating it now...
立即再次运行脚本。现在 data.txt 已经存在,因此脚本应该执行路径 A:
./check_file.sh
输出:
data.txt exists.
现在,你的脚本已经具备「幂等性」——这是一个听起来很专业的词,意思是:即使运行 100 次,脚本也始终能确保最终结果正确(文件存在),而不会崩溃。
这个词在 DevOps 中经常出现。幂等操作可以安全地重复执行,因为最终状态比命令执行了多少次更重要。这会让自动化更加可靠,尤其是在任务需要重试时。
检查 Root 权限
Linux 中有些入口受到锁定,只有超级用户(Root)拥有钥匙。如果你以普通用户身份运行系统维护脚本,脚本会因「Permission Denied」而失败。
优秀的脚本会在尝试打开入口之前,先检查你的身份。
在 Linux 中,每个用户都有一个数字,即 UID。
- Root 的 UID 始终为 0。
- 普通用户的 UID 通常为 1000 或更高。
编写一个检查用户身份的脚本。
创建 check_root.sh:
nano check_root.sh
输入以下代码:
#!/bin/bash
if [ "$UID" -eq 0 ]; then
echo "You are running this script as root."
else
echo "You are running this script as a regular user."
fi
解析:
$UID:保存当前用户 ID 数字的变量。-eq:「EQuals」的缩写,用于比较数字。(比较字符串时使用=。)
这是测试语法的另一个示例。在 [ ... ] 中比较数字时,Bash 使用 -eq、-ne、-lt 和 -gt 等运算符。它们与字符串比较运算符不同,因为 Shell 需要知道当前比较的是字符串还是数值。
保存并退出。为脚本添加可执行权限:
chmod +x check_root.sh
测试
由于你以 labex 用户身份登录,因此是普通用户。
直接运行脚本:
./check_root.sh
脚本检测到你的 ID 不为 0,并显示:
You are running this script as a regular user.
现在,使用 sudo 临时借用超级用户权限:
sudo ./check_root.sh
sudo 只会针对这条命令将你的 ID 切换为 0。脚本检测到这一点后,会显示:
You are running this script as root.
专业的安装脚本就是这样工作的——除非你是 root,否则它们会拒绝运行!
目的并不是要求所有操作都必须使用 root,而是在执行受保护的操作前先检查权限。编写良好的脚本会提前停止并给出清晰说明,而不是执行到一半才产生令人困惑的权限错误。
总结
你刚刚为脚本添加了一个「大脑」!
在本实验中,你学习了:
- 门卫(
if):提出「这个文件是否存在?」这样的问题(-f)。 - 分叉(
else):当答案为「否」时提供备用方案。 - 身份检查:使用数字比较(
-eq)验证用户权限。
现在,你的脚本不再只是命令列表,而是能够适应运行环境的智能程序。



