sh 与 bash 的区别详解
1. 历史背景
-
sh(Bourne Shell) :由 Stephen Bourne 在 1977 年开发,是 Unix 系统的默认 Shell。语法简洁,但功能有限。
-
bash(Bourne Again Shell) :由 Brian Fox 在 1989 年开发,是
sh的扩展版本,兼容sh语法并添加了大量新特性(如命令行编辑、历史记录等)。
2. 主要区别与示例
2.1 脚本声明差异
-
sh脚本默认使用
#!/bin/sh,遵循 POSIX 标准。sh#!/bin/sh echo "Hello, sh!" -
bash脚本使用
#!/bin/bash,支持非 POSIX 扩展语法。bash#!/bin/bash echo "Hello, bash!"
2.2 变量与数组
-
sh不支持数组
sh原生不支持数组,需用字符串模拟:sh#!/bin/sh list="one two three" for item in $list; do echo "$item" done -
bash支持数组
bash提供原生数组语法:bash#!/bin/bash arr=("one" "two" "three") echo "First element: ${arr[0]}" # 输出 "one"
2.3 字符串操作
-
sh功能有限字符串截取需依赖外部命令(如
cut):sh#!/bin/sh str="abcdef" substr=$(echo "$str" | cut -c1-3) # 输出 "abc" -
bash内置字符串操作支持直接截取:
bash#!/bin/bash str="abcdef" substr=${str:0:3} # 输出 "abc"
2.4 条件测试语法
-
sh使用test或[ ]
sh不支持[[ ]],需严格遵循空格规则:sh#!/bin/sh if [ "$a" -eq 1 ] && [ "$b" -eq 2 ]; then echo "Conditions met." fi -
bash支持[[ ]]更安全的语法,支持正则匹配:
bash#!/bin/bash if [[ $a == 1 && $b =~ ^2 ]]; then echo "Conditions met." fi
2.5 命令行扩展
-
bash特有扩展-
大括号扩展 :
bashecho {1..5} # 输出 "1 2 3 4 5" -
进程替换 :
bashdiff <(ls dir1) <(ls dir2)
sh不支持上述语法。 -
2.6 错误处理
-
bash支持更多选项如
set -e(出错退出)和set -o pipefail(管道错误捕获):bash#!/bin/bash set -euo pipefail grep "pattern" file.txt | sortsh对部分选项支持有限。
3. 兼容性
-
bash兼容模式
通过#!/bin/sh调用bash时,若bash是系统默认 Shell,会尽量模拟sh行为:bash# 使用 `bash --posix` 强制启用 POSIX 模式
4. 总结与使用场景
| 场景 | 推荐 Shell |
|---|---|
| 需严格遵循 POSIX 标准 | sh |
| 需要高级功能或交互式操作 | bash |
| 跨平台脚本 | sh(避免依赖扩展) |
-
验证当前 Shell :
bashecho $SHELL # 显示默认 Shell echo $0 # 显示当前运行 Shell