Linux 作为一款开源的类 Unix 操作系统,其强大的命令行工具是用户与系统交互的核心,在众多命令行工具中,bash 和 sh 是两个最常被提及的 shell,它们不仅是用户与 Linux 内核沟通的桥梁,更是自动化脚本编写和系统管理的基础,本文将深入探讨 bash 和 sh 的基本概念、核心差异、使用场景及实践技巧,帮助读者更好地理解和使用这两个关键工具。

shell 的基本概念与作用
Shell 是 Linux/Unix 系统中的一个特殊程序,它充当着用户与内核之间的翻译官,当用户在终端输入命令时,shell 会解析这些命令,调用相应的程序执行,并将结果返回给用户,除了命令解释功能,shell 还提供了编程能力,用户可以通过编写脚本(一系列命令的集合)实现自动化任务,如文件批处理、系统监控、日志分析等,Linux 中常见的 shell 包括 bash、sh、csh、ksh 等,bash 和 sh 是最基础且应用最广泛的。
sh:Shell 的基石
sh(Bourne Shell)是由 Stephen Bourne 于 1977 年在贝尔实验室开发的,是 Unix 系统的第一个真正意义上的 shell,它的设计简洁高效,语法规范,成为后来许多现代 shell 的基础,在大多数 Linux 发行版中,/bin/sh 通常是一个指向其他 shell(如 bash 或 dash)的符号链接,目的是保持与旧版 Unix 脚本的兼容性。
sh 的核心特性
- 语法简洁:sh 的语法规则简单,没有复杂的扩展功能,适合编写基础的系统管理脚本。
- 兼容性强:作为最早的 shell,sh 的脚本在几乎所有 Unix-like 系统中都能运行,具有良好的可移植性。
- 轻量级:sh 占用系统资源较少,在对性能要求较高的嵌入式系统或轻量级环境中更受青睐。
sh 脚本示例
以下是一个简单的 sh 脚本,用于备份指定目录:
#!/bin/sh # 备份脚本示例 SOURCE_DIR="/home/user/documents" BACKUP_DIR="/backup" DATE=$(date +%Y%m%d) tar -czf "$BACKUP_DIR/backup_$DATE.tar.gz" "$SOURCE_DIR" echo "Backup completed: $BACKUP_DIR/backup_$DATE.tar.gz"
脚本第一行的 #!/bin/sh 指定了解释器, 用于命令替换,获取当前日期并作为备份文件名的一部分。

bash:增强的 Shell 体验
bash(Bourne-Again Shell)由 Brian Fox 于 1989 年开发,作为 sh 的替代品和增强版,它是目前大多数 Linux 发行版的默认 shell,在兼容 sh 的基础上,引入了大量新特性和改进功能,极大地提升了用户体验和脚本编写效率。
bash 的核心特性
- 兼容 sh:bash 完全兼容 sh 的语法,因此所有 sh 脚本都可以在 bash 环境中直接运行。
- 命令行编辑:支持命令历史记录、光标移动、自动补全等功能,方便用户快速输入和编辑命令。
- 数组支持:支持一维数组,便于处理批量数据。
- 进程控制:提供了更灵活的进程管理机制,如作业控制(
&、Ctrl+Z、fg、bg)。 - 丰富的内置命令:如
alias(命令别名)、source(执行脚本文件)、let(算术运算)等。 - 正则表达式扩展:支持更强大的字符串匹配和模式替换功能。
bash 脚本示例
以下是一个 bash 脚本,使用数组遍历并打印文件列表:
#!/bin/bash
# 使用数组遍历文件
files=("file1.txt" "file2.txt" "file3.txt")
for file in "${files[@]}"; do
if [ -f "$file" ]; then
echo "File exists: $file"
else
echo "File not found: $file"
fi
done
脚本中 ${files[@]} 表示数组的所有元素,-f 是测试文件是否为普通文件的参数。
bash 与 sh 的主要区别
尽管 bash 兼容 sh,但两者在功能和语法上仍存在显著差异,以下是两者的核心对比:

| 特性 | sh | bash |
|---|---|---|
| 默认交互界面 | 无命令行编辑功能 | 支持命令历史、光标移动、自动补全 |
| 数组支持 | 不支持 | 支持一维数组,可通过 arr[index]=value 赋值 |
| 算术运算 | 仅通过 expr 命令实现 |
支持 let、、$[ ] 等多种方式 |
| 函数定义 | 语法简单,无局部变量支持 | 支持局部变量(local 关键字) |
| 正则表达式 | 功能有限 | 支持 操作符进行模式匹配 |
| 进程控制 | 基础的作业控制 | 增强的作业控制,支持 coproc 协同进程 |
| 内置命令 | 较少(如 cd、pwd、export) |
丰富(如 alias、source、hash) |
如何选择 bash 与 sh?
选择使用 bash 还是 sh 取决于具体需求:
- 兼容性与可移植性:如果脚本需要在多种 Unix 系统(如旧版 Solaris、嵌入式设备)中运行,建议使用 sh,避免依赖 bash 的扩展功能。
- 功能需求:对于需要复杂脚本逻辑、数组操作或交互式命令行操作的场景,bash 是更优选择。
- 系统默认:大多数现代 Linux 发行版默认使用 bash,日常开发和运维中直接使用 bash 即可满足需求。
实践技巧与最佳实践
- 明确指定解释器:脚本开头使用
#!/bin/bash或#!/bin/sh,确保系统使用正确的 shell 执行。 - 变量规范:变量名建议使用大写字母,如
PATH、HOME;引用变量时用双引号包裹(如"$VAR"),避免空格和特殊字符导致解析错误。 - 错误处理:使用
set -e使脚本在命令失败时立即退出,或通过if语句检查命令执行状态(如if [ $? -ne 0 ]; then ... fi)。 - 注释清晰:为复杂逻辑添加注释,提高脚本可读性和可维护性。
- 测试与调试:通过
bash -x script.sh运行脚本,查看每条命令的执行过程,便于调试。
sh 作为 shell 的鼻祖,以其简洁和兼容性奠定了基础;而 bash 在其基础上通过丰富的功能和易用性成为 Linux 系统的主流选择,理解两者的区别与联系,掌握它们的使用场景和编程技巧,不仅能提升命令行操作效率,更能为自动化运维和脚本开发打下坚实基础,无论是简单的系统任务还是复杂的逻辑处理,合理选择和运用 bash 与 sh,都能让 Linux 系统管理事半功倍。


















