【珍藏版】Bash 必学的 5 种模式与避错技巧
通过之前的 Bash 入门系列,您已经掌握了从基本命令到简单脚本编写的“黑窗”操作基础。想必您已经感受到,通过组合命令,日常工作变得轻松了一些。大家辛苦了!
好了,作为 Bash 篇的收官之作,这次我们将更进一步,从“能跑就行”的脚本,升级到“安全、易读、不易出错”的专业级脚本。我们将传授 5 个特别重要的模式,以及避免新手常犯“陷阱”的技巧。
接下来要介绍的并非新的高难度命令,而是关于“如何正确使用”已有知识的技巧,好比开车的诀窍。就像刚学会开车的人要学习在雨天和夜路安全行驶的技巧一样,通过今天的文章,您也将掌握在任何情况下都能安心执行的脚本编写方法!
模式 1:变量务必用“双引号”括起来!
这是 Bash 脚本中的绝对黄金法则。忘记用双引号 " " 包裹变量,是导致意外错误的最大原因。尤其当变量中包含空格时,问题会变得非常明显。
常见的错误:不加引号的变量
例如,我们来看下面这个试图创建包含空格的目录名的脚本。
#!/bin/bash
DIR_NAME="My Project"
mkdir $DIR_NAME
执行这个脚本后,Bash 会将命令解释为 mkdir My Project,结果会创建出 “My” 和 “Project” 这两个独立的目录。这并非我们期望的结果。
最佳实践:用 " " 包裹变量
要解决这个问题,只需将变量用双引号括起来即可。这样,Bash 就会正确地将包含空格的整个字符串识别为“一个整体”。
#!/bin/bash
DIR_NAME="My Project"
mkdir "$DIR_NAME" # 用双引号包裹变量!
echo "目录 '$DIR_NAME' 已创建。"
这个简单的习惯会让您的脚本变得更加健壮。请牢记:“变量总是用双引号括起来”。
模式 2:出错时立即停止的安全设计
Bash 脚本有一个可怕之处:即使中途某个命令执行失败,它也会毫不在意地继续执行后续的命令。例如,一个“先移动到某个目录,再在其中删除文件”的脚本,如果移动失败了会怎样?很可能导致在错误的位置删除了文件,造成巨大灾难。
为防止这种情况,请在脚本开头写上这句“咒语”:
set -e
set -e 就像一个“安全装置”,一旦脚本中任何一个命令执行出错,它就会立即中止脚本的运行。让我们通过下面的脚本看看它的效果。
#!/bin/bash
set -e # 打开安全装置
echo "开始处理..."
# 尝试移动到一个不存在的目录,这里会发生错误
cd /non-existent-directory
# 因为有 set -e,这一行绝不会被执行
echo "这条消息不会显示。"
执行这个脚本时,处理流程会在 cd 命令失败的那一刻停止,最后的 echo 命令不会被执行。对于执行重要操作的脚本,请务必写上这一行。
模式 3:将命令的执行结果存入变量
在编写脚本时,我们经常会遇到需要“将一个命令的执行‘结果’用于另一个命令或变量”的场景。例如,想在备份文件名中加入当天的日期。
这时可以使用命令替换 (Command Substitution) 功能。写法是 $(命令)。
#!/bin/bash
set -e
# 获取 YYYY-MM-DD 格式的今天日期,并存入变量
TODAY=$(date "+%Y-%m-%d")
# 将日期整合进文件名
BACKUP_FILENAME="backup_${TODAY}.tar.gz"
echo "备份文件名: $BACKUP_FILENAME"
# tar -czf "$BACKUP_FILENAME" /path/to/backup/source
$(date "+%Y-%m-%d") 这部分会被 date 命令的执行结果(例如:2025-07-06)所替换。这样就能轻松生成动态且易于理解的文件名。
模式 4:安全地逐行处理文件
读取文本文件(如域名列表、URL 列表等),并对每一行进行处理,是脚本的典型应用场景。但是,这个操作有一个新手容易掉入的“陷阱”。
常见的错误模式
像 for line in $(cat file.txt) 这样的写法,在文件名包含空格时无法正确处理,应当避免。
安全的最佳实践:`while read` 循环
安全且高效地逐行处理文件的标准模式是使用 while read 循环。它看起来可能有点复杂,但最好的方法是将其作为固定格式记住。
首先,我们准备一个待处理的列表文件 `domains.txt`。
example.com
example.net
example.org
接下来,是读取并处理这个文件的脚本。
#!/bin/bash
set -e
INPUT_FILE="domains.txt"
while IFS= read -r line
do
echo "Processing domain: $line"
# 在这里执行 ping $line 或 curl http://$line/ 等操作
done < "$INPUT_FILE"
这个语法可以保留行首和行尾的空格,并能正确处理特殊字符,因此可以应用于所有文本文件的处理。
模式 5:安全地创建和删除临时文件
在脚本处理过程中,有时需要创建临时的工作文件。这时,如果硬编码文件名,如 /tmp/my_temp_file,是很危险的。如果其他程序正在使用同名文件,或者脚本被同时多次执行,文件就可能被覆盖。
要安全地创建临时文件,请使用 mktemp 命令。它会创建一个独一无二、不会与任何文件重名的空文件。
#!/bin/bash
set -e
# 创建一个安全的临时文件,并将其名称存入变量
TEMP_FILE=$(mktemp)
# 确保在脚本退出时(无论是正常结束、出错还是被中断)总是删除该临时文件
trap 'rm -f "$TEMP_FILE"' EXIT
echo "已创建临时文件: $TEMP_FILE"
echo "正在向此文件写入数据..."
echo "some temporary data" > "$TEMP_FILE"
echo "文件内容:"
cat "$TEMP_FILE"
echo "处理完成。临时文件将被自动删除。"
此外,通过结合使用 trap 命令,您可以预设一个“清理”操作:“无论脚本因何种原因退出,最后都必须删除这个临时文件”。这可以防止服务器上残留不必要的垃圾文件。
总结
辛苦了!至此,Bash 入门系列就全部完结了。在最后一期中,我们学习了 5 个重要的模式,它们能让您的脚本从“玩具”升华为“专业工具”。
- 🛡️ 变量务必用
" "包裹:防止因空格导致异常的基本中的基本。 - 🚨 使用
set -e在出错时立即停止:防止意外事故的安全装置。 - 🔄 使用
$(命令)来利用执行结果:实现动态处理的强大武器。 - 📖 使用
while read逐行处理文件:安全可靠的文件读取标准做法。 - 🗑️ 使用
mktemp和trap确保善后工作万无一失:专业人士处理临时文件的安全方式。
只要有意识地使用这些模式,您编写的脚本的可靠性就会大大增加,并且会变成易于维护的代码,方便未来的自己或他人阅读。请务必在今后的脚本编写中活用它们。衷心祝愿您的 Web 制作生涯,在获得了 Bash 这个强大工具后,变得更加富有创造性和效率!