sh脚本(长文解析)

什么是 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"

✅ 使用说明:

  1. 将脚本保存为 backup_project.sh
  2. chmod +x backup_project.sh
  3. 手动测试:./backup_project.sh
  4. 用 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脚本为你打工。