什么是 sh脚本?从零开始理解 shell 脚本的本质
你有没有遇到过这样的场景:每天重复执行几个命令,比如备份文件、清理日志、启动服务?手动敲命令不仅费时,还容易出错。这时候,sh脚本就派上用场了。
sh脚本,本质上就是一组可以自动执行的命令集合。它就像一个“自动化流水线”,你只需要启动它,剩下的工作就由系统自动完成。它的核心是 Shell,也就是 Linux / Unix 系统的命令行解释器。sh 是 Bourne Shell 的缩写,是最早期的 Shell 之一,也是大多数系统默认支持的脚本环境。
想象一下,你每天要做的工作,就像一条流水线上的工人:打开电脑 → 进入项目目录 → 拉取最新代码 → 编译 → 测试 → 部署。如果每一步都要手动操作,一天下来累得不行。而 sh脚本,就是把你所有的操作封装成一个“一键启动”的按钮。
✅ 关键点:sh脚本不是编程语言,而是命令的“剧本”。它本身不编译,而是逐行解释执行。
如何创建和运行一个最简单的 sh脚本
创建一个 sh脚本非常简单,只需要三步:编写、赋予执行权限、运行。
第一步:创建脚本文件
使用你喜欢的文本编辑器(比如 vim、nano、VS Code),新建一个文件,命名为 hello.sh。
#!/bin/sh
echo "Hello, World!"
📌 注意:第一行
#!/bin/sh是必须的,它称为 shebang,告诉操作系统用 sh 解释器来运行这个脚本。
第二步:赋予执行权限
在终端中运行以下命令:
chmod +x hello.sh
chmod +x 的意思是“增加可执行权限”。没有这一步,系统会拒绝运行你的脚本。
第三步:运行脚本
./hello.sh
输出结果:
Hello, World!
✅ 成功!你已经运行了第一个 sh脚本。
变量、输入与输出:sh脚本的“内存”与“交流方式”
sh脚本虽然简单,但也有变量、输入、输出这些基础能力。它们就像人脑的记忆和说话能力。
变量定义与使用
在 sh脚本中,变量不需要声明类型,直接赋值即可。
#!/bin/sh
name="Alice"
echo "欢迎,$name!"
运行结果:
欢迎,Alice!
⚠️ 错误示例:
name = "Alice"会报错,因为等号两边不能有空格。
读取用户输入
使用 read 命令可以从终端获取用户输入。
#!/bin/sh
echo "请输入你的名字:"
read username
echo "你好,$username!欢迎使用 sh脚本。"
运行后,终端会暂停等待输入,输入内容后按回车,脚本继续执行。
条件判断与循环:让 sh脚本“思考”
一个聪明的 sh脚本不能只会按顺序执行命令,它还应该能“判断”和“循环”。
if 条件判断
#!/bin/sh
echo "请输入一个数字:"
read num
if [ $num -gt 10 ]; then
echo "这个数字大于 10!"
elif [ $num -eq 10 ]; then
echo "这个数字等于 10。"
else
echo "这个数字小于 10。"
fi
✅ 小技巧:条件判断中,
[和]之间必须有空格,否则会报错。
for 循环:重复执行任务
#!/bin/sh
for i in 1 2 3 4 5; do
echo "当前数字是:$i"
done
输出:
当前数字是:1
当前数字是:2
当前数字是:3
当前数字是:4
当前数字是:5
函数封装:提升 sh脚本的可复用性
当你的 sh脚本越来越长,重复代码越来越多时,就可以用函数来“封装”逻辑。
#!/bin/sh
greet() {
local name="$1"
# $1 是函数的第一个参数
# local 表示局部变量,避免污染全局环境
if [ -z "$name" ]; then
echo "请输入名字!"
return 1
# return 1 表示函数执行失败
fi
echo "你好,$name!今天过得怎么样?"
}
greet "张三"
greet # 传空参数,会提示错误
✅ 函数是 sh脚本中组织代码的“积木块”,让脚本更清晰、更易维护。
实战案例:自动备份脚本
我们来写一个真实的 sh脚本,用于每天自动备份某个目录。
#!/bin/sh
src_dir="/home/user/project"
backup_dir="/backup"
log_file="/var/log/backup.log"
date_str=$(date "+%Y-%m-%d")
backup_file="$backup_dir/project_backup_$date_str.tar.gz"
if [ ! -d "$backup_dir" ]; then
mkdir -p "$backup_dir"
echo "$(date): 创建备份目录 $backup_dir" >> "$log_file"
fi
tar -czf "$backup_file" -C "$(dirname "$src_dir")" "$(basename "$src_dir")"
if [ $? -eq 0 ]; then
echo "$(date): 备份成功:$backup_file" >> "$log_file"
else
echo "$(date): 备份失败!" >> "$log_file"
exit 1
fi
echo "备份完成:$backup_file"
✅ 使用说明:
- 将脚本保存为
backup_project.shchmod +x backup_project.sh- 手动测试:
./backup_project.sh- 用 cron 定时任务每天运行一次(后续可扩展)
常见陷阱与最佳实践
在使用 sh脚本时,有几个“坑”特别容易踩中:
| 常见问题 | 正确做法 | 说明 |
|---|---|---|
| 变量赋值两边有空格 | name="Alice" |
name = "Alice" 会报错 |
| if 条件中缺少空格 | [ $num -gt 10 ] |
必须写成 [ $num -gt 10 ],中括号前后有空格 |
| 忘记加执行权限 | chmod +x script.sh |
否则无法运行 |
使用 echo 时未转义特殊字符 |
echo "Hello $name" |
变量引用正确,但注意 ! 等符号可能被 shell 解释 |
✅ 最佳实践建议:
- 所有脚本开头写
#!/bin/sh- 使用
set -euo pipefail开启严格模式(可选)- 重要操作加日志记录
- 多用函数拆分逻辑
- 避免直接使用
eval,防止注入风险
总结:sh脚本是自动化工作的“第一把钥匙”
sh脚本虽然看起来简单,但它却是 Linux 系统自动化管理的基石。从最基础的“打印一句话”,到复杂的“定时备份+监控+告警”,sh脚本都能胜任。
它不依赖任何复杂的框架,运行速度快,兼容性强,是运维、开发、测试等岗位必备技能。
✅ 无论你是初学者,还是已有经验的开发者,掌握 sh脚本,都能让你的日常工作更高效、更可靠。
别再手动敲命令了,试着把重复操作写成 sh脚本。哪怕只是一个简单的 hello.sh,也是你迈向自动化世界的起点。
从今天起,让 sh脚本为你打工。