Skip to content

可移植性

  • 状态:已验证
  • 来源:对话整理
  • 更新时间:2026-03-12

关键结论

  • 引号规则和 bash/sh 差异是 Shell 可移植性的核心。
  • 如果脚本依赖数组、[[ ... ]]source、进程替换或 declare -A,就应明确要求 Bash。

详细分析

  • 单引号、双引号和未加引号的变量会直接影响空格、换行、通配符和变量展开行为。
  • 很多“在本机能跑”的脚本,实际问题来自默认 shell 与 Bash 语法不一致。

可执行步骤

  1. 先判断脚本目标环境是否固定为 Bash。
  2. 若需要兼容 /bin/sh,避免使用 Bash 专有语法。
  3. 涉及字符串和路径时,优先显式加引号。
  4. 在脚本头明确写出解释器。

命令 / 配置 / 代码

高频写法清单:

  • 'text'
  • "${var}"
  • \
  • #!/bin/sh
  • #!/usr/bin/env bash
  • [ ... ] vs [[ ... ]]

引号与转义规则

  • 'text' 单引号,内容原样保留,不展开变量和命令。
  • "text" 双引号,保留空格,同时允许变量展开和命令替换。
  • \ 转义单个字符。
  • $(cmd) 命令替换。
  • `cmd` 旧式命令替换,不推荐优先使用。
bash
name="alice"
echo '$name'
echo "$name"
echo \$name
echo "$(date +%F)"

Bash 与 sh 可移植性差异

  • #!/bin/sh 使用更基础的 shell,强调可移植性。
  • #!/usr/bin/env bash 明确要求 Bash。
  • [ ... ] 更通用的测试语法。
  • [[ ... ]] Bash 扩展语法。
  • arr=("a" "b") Bash 数组语法,sh 不支持。
  • declare -A Bash 关联数组,sh 不支持。
  • <(cmd) Bash 进程替换,sh 不支持。
bash
#!/bin/sh
bash
#!/usr/bin/env bash

可移植性建议:

  • 如果脚本用到了数组、[[ ... ]]sourceselect=~declare、进程替换,就应明确使用 Bash。
  • 如果目标环境不确定,且语法需求简单,优先考虑 sh 兼容写法。
  • 写知识库中的脚本模板时,应先标明脚本依赖的是 bash 还是 sh

风险与注意事项

  • 未加引号的变量最容易在处理空格、换行和通配符时出错。
  • 正则匹配使用 =~ 时,右侧通常不要加引号,否则可能改变匹配行为。
  • 可移植性要求不清时,容易把 Bash 语法误写到 sh 脚本中。