限时福利领取


为什么 Shell 选择让人头疼?

刚接触 Linux 时,发现同样的脚本在不同机器上表现不一致:

  • 本地开发机运行正常,放到服务器却报 [[ not found 错误
  • 简单的循环处理,在树莓派上执行速度明显变慢
  • 使用 echo {1..10} 时输出结果不符合预期

Shell选择困惑

后来才发现,这往往是因为系统默认 Shell 不同——可能是 Dash(Debian系默认)或 Bash(多数桌面环境默认)。

Dash vs Bash 核心差异对比

| 特性 | Dash | Bash | |---------------------|-----------------------|------------------------| | 启动速度 | ⚡ 更快(轻量级) | 🐢 稍慢(功能丰富) | | [[ ]] 条件判断 | ❌ 不支持 | ✅ 支持 | | 数组操作 | 仅基础支持 | 完整功能 | | {1..10} 扩展 | 原样输出 | 生成数字序列 | | POSIX 兼容 | 严格模式 | 扩展模式 |

实战:检查与编写兼容脚本

第一步:确认当前 Shell

ls -l /bin/sh  # 显示链接指向 dash 还是 bash
# 典型输出:/bin/sh -> dash

兼容脚本示例

#!/bin/sh
# 同时兼容 Dash/Bash 的脚本模板

# 变量处理:统一使用 ${var} 格式
name="World"
echo "Hello ${name}"

# 条件判断:使用 POSIX 标准 [ ] 语法
if [ "$UID" -eq 0 ]; then
    echo "Running as root"
else
    echo "Please run as root"
fi

# 数组兼容写法(Bash可用,Dash会忽略)
data="item1 item2 item3"
for item in ${data}; do
    echo "Processing ${item}"
done

五大常见踩坑点

  1. 字符串比较
    Dash 必须用 [ "$a" = "$b" ],而 Bash 允许 [[ $a == $b ]]

  2. 算术运算
    Dash 需 $(( )),如 sum=$(( 1 + 2 ))

  3. 函数返回值
    Dash 只能用 return 0,Bash 支持 return $?

  4. 通配符扩展
    Dash 不支持 *.txt 在变量中展开,需显式使用 ls

  5. 调试工具
    强烈推荐安装 shellcheck

    sudo apt install shellcheck
    shellcheck your_script.sh

Shell调试

性能实测对比

测试 10000 次循环(单位:秒):

# Bash
time for ((i=0; i<10000; i++)); do :; done
# 输出:real 0m0.023s

# Dash
time sh -c 'i=0; while [ $i -lt 10000 ]; do i=$((i+1)); done'
# 输出:real 0m0.011s

结论:Dash 在简单循环中确实更快,但复杂脚本可能需 Bash 的特性支持。

进阶思考题

  1. 如何在 Dash 脚本中临时调用 Bash 特有的关联数组?
  2. 服务器部署时,为什么建议在 shebang 写 /bin/bash 而非 /bin/sh
  3. 当需要同时兼容 macOS(默认 Bash 3.x)和 Linux 时,要特别注意哪些语法?

小贴士:生产环境中,可以在脚本开头通过 [ -z "$BASH" ] && exec bash "$0" "$@" 自动切换到 Bash

Shell学习路径

Logo

音视频技术社区,一个全球开发者共同探讨、分享、学习音视频技术的平台,加入我们,与全球开发者一起创造更加优秀的音视频产品!

更多推荐