bash__0">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 标准。#!/bin/sh echo "Hello, sh!"
-
bash
脚本
使用#!/bin/bash
,支持非 POSIX 扩展语法。bash">#!/bin/bash echo "Hello, bash!"
2.2 变量与数组
-
sh
不支持数组
sh
原生不支持数组,需用字符串模拟:#!/bin/sh list="one two three" for item in $list; do echo "$item" done
-
bash">#!/bin/bash arr=("one" "two" "three") echo "First element: ${arr[0]}" # 输出 "one"
2.3 字符串操作
-
sh
功能有限
字符串截取需依赖外部命令(如cut
):#!/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
不支持[[ ]]
,需严格遵循空格规则:#!/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
特有扩展- 大括号扩展:
bash">echo {1..5} # 输出 "1 2 3 4 5"
- 进程替换:
bash">diff <(ls dir1) <(ls dir2)
sh
不支持上述语法。 - 大括号扩展:
2.6 错误处理
-
bash
支持更多选项
如set -e
(出错退出)和set -o pipefail
(管道错误捕获):bash">#!/bin/bash set -euo pipefail grep "pattern" file.txt | sort
sh
对部分选项支持有限。
3. 兼容性
bash
兼容模式
通过#!/bin/sh
调用bash
时,若bash
是系统默认 Shell,会尽量模拟sh
行为:bash"># 使用 `bash --posix` 强制启用 POSIX 模式
4. 总结与使用场景
场景 | 推荐 Shell |
---|---|
需严格遵循 POSIX 标准 | sh |
需要高级功能或交互式操作 | bash |
跨平台脚本 | sh (避免依赖扩展) |
- 验证当前 Shell:
bash">echo $SHELL # 显示默认 Shell echo $0 # 显示当前运行 Shell