Bash学习 - 第6章:Bash Features,第12节:Shell Compatibility Mode

本文为 Bash Reference Manual第6章:Bash Features 第12节:Shell Compatibility Mode 的读书笔记。

完整的笔记目录参见Bash学习笔记总目录

6.12 Shell Compatibility Mode

Bash-4.0 引入了 shell 兼容性级别的概念,这一概念通过 shopt 内置命令的一组选项来指定(compat31、compat32、compat40、compat41 等)。当前只有一个兼容性级别------每个选项是互斥的。兼容性级别旨在允许用户选择旧版本中与新版本不兼容的行为,以便在迁移脚本以使用当前特性和行为时使用。它被设计为一种临时解决方案。

本节未提及特定版本的标准行为(例如,设置 compat32 意味着在正则表达式匹配操作符右侧加引号会将特殊正则字符作为普通字符引号处理,这是 bash-3.2 及后续版本的默认行为)。

如果用户启用了例如 compat32,这可能会影响其他兼容级别的行为,直到包括当前的兼容级别。其理念是每个兼容级别控制 Bash 在该版本中发生变化的行为,但这些行为可能在早期版本中也存在。例如,使用 [[ 命令进行基于本地化的比较的更改出现在 bash-4.1,而早期版本使用基于 ASCII 的比较,因此启用 compat32 也会启用基于 ASCII 的比较。这种粒度可能不足以满足所有用途,因此用户应谨慎使用兼容级别。请阅读特定功能的文档以了解当前行为。

Bash-4.3 引入了一个新的 shell 变量:BASH_COMPAT。赋值给该变量的值(如 4.2 的十进制版本号,或对应于 compatNN 选项的整数,如 42)决定了兼容级别。

从 bash-4.4 开始,Bash 开始弃用旧的兼容级别。最终,这些选项将被移除,取而代之的是 BASH_COMPAT。

Bash-5.0 是最后一个为之前版本提供单独 shopt 选项的版本。在 bash-5.0 之后的版本中,BASH_COMPAT 是唯一控制兼容级别的机制。

下表描述了每个兼容性级别设置所控制的行为变化。compatNN 标签用作将兼容性级别设置为 NN 的简写,可通过以下机制之一进行设置。对于 bash-5.0 之前的版本,可以使用相应的 compatNN shopt 选项来设置兼容性级别。对于 bash-4.3 及更高版本,推荐使用 BASH_COMPAT 变量,并且对于 bash-5.1 及更高版本,这是必须的。


compat31

  • 引用 [[ 命令的正则表达式匹配操作符 (=~) 的右侧没有特殊效果

compat40

  • [[ 命令中的 '<' 和 '>' 操作符在比较字符串时不考虑当前区域设置;它们使用 ASCII 排序。Bash 4.1 之前的版本使用 ASCII 排列和 strcmp(3);Bash 4.1 及以后版本使用当前区域设置的排列顺序和 strcoll(3)。

compat41

  • 在 POSIX 模式下,time 后面可以跟选项,仍然会被识别为保留字(这是 POSIX 解释 267)。
  • 在 POSIX 模式下,解析器要求双引号包围的 ${...} 参数扩展的单词部分中出现偶数个单引号,并将其特殊处理,以便单引号内的字符被视为已引用(这是 POSIX 解释 221)。

compat42

  • 双引号模式替换中的替换字符串不会像 bash-4.2 之后的版本那样进行引号去除。
  • 在 POSIX 模式下,单引号在展开双引号 ${...} 参数扩展的单词部分时被认为是特殊的,可以用来引用闭合大括号或其他特殊字符(这是 POSIX 解释 221 的一部分);在后续版本中,单引号在双引号单词扩展内不再特殊。

compat43

  • 单词扩展错误被视为非致命错误,会导致当前命令失败,即使在 POSIX 模式下(默认行为是将其视为致命错误,使 shell 退出)。
  • 在执行 shell 函数时,循环状态(while/until 等)不会重置,因此在该函数中使用 break 或 continue 会影响调用上下文中的循环。Bash 4.4 及以后版本会重置循环状态以防止这种情况。

compat44

  • Shell 会设置 BASH_ARGV 和 BASH_ARGC 使用的值,使它们即使在未开启扩展调试模式下,也能展开为 shell 的位置参数。
  • 子 shell 会继承其父上下文的循环,因此 break 或 continue 会导致子 shell 退出。Bash 5.0 及以后版本会重置循环状态以防止退出。
  • 变量赋值紧跟在设置属性的内置命令(如 export 和 readonly)之前,即使 shell 不在 POSIX 模式下,仍然会影响调用环境中同名变量。

compat50(使用 BASH_COMPAT 设置)

  • Bash-5.1 改变了 $RANDOM 的生成方式,以引入稍微更多的随机性。如果将 shell 兼容级别设置为 50 或更低,它会恢复到 bash-5.0 及以前版本的方法,因此通过给 RANDOM 分配值来为随机数生成器设定种子时,将会生成与 bash-5.0 相同的序列。
  • 如果命令哈希表为空,bash-5.1 以前的 Bash 版本会打印相应的提示信息,即使生成的输出可以作为输入重新使用。Bash-5.1 在提供 -l 选项时会抑制该提示信息。

compat51(使用BASH_COMPAT设置)

  • unset内置命令会在给定参数如"a@'的情况下,unset数组a。Bash-5.2 会取消键为 '@' 的元素(关联数组),或者移除所有元素而不重置数组(索引数组)。
  • 算术命令(((...)))和对命题的算术表达式可以展开多次。
  • 作为[[条件命令中算术算子参数的表达式可以多次展开。
  • 子串参数大括号展开中的表达式可以展开不止一次。
  • $(( ...)) 词扩展中的表达式可以展开多次。
  • 作为索引数组下标的算术表达式可以展开多次。
  • 当给定参数 'A@'(其中 A 是存在的结合数组)测试 -v 返回真,且该数组包含任何集合元素。Bash-5.2 将查找并报告一个名为 '@' 的密钥。
  • ${Parameter=value} 字展开会返回值,前提是尚未进行任何变量特定变换(例如转换为小写)。Bash-5.2 将返回变量的最终值。
  • 解析命令替换的表现就像启用了globbing(见 The Shopt Builtin)一样,因此解析包含 extglob 模式的命令替换(例如作为 shell 函数的一部分)不会失败。这假设意图是在命令执行并进行字扩展之前启用 extglob。如果在执行命令时还没有启用 extglob,它将在字扩展时失败。

compat52(使用 BASH_COMPAT 设置)

  • 当 test 内建命令接收到五个或更多参数时,会使用其历史算法解析括号括起的子表达式。
  • 如果向 bind 内建命令提供了 -p 或 -P 选项,bind 会将选项处理后的剩余参数视为可绑定的命令名称,并显示绑定到这些命令的任何按键序列,而不是将参数视为要绑定的按键序列。
  • 交互式 shell 在读取脚本时会通知用户已完成的作业。较新的版本会延迟通知,直到脚本执行完成。

示例:

bash 复制代码
$ echo $BASH_VERSION
5.3.0(1)-release

# compat44以上需要使用BASH_COMPAT 设置
$ shopt |grep compat
compat31                off
compat32                off
compat40                off
compat41                off
compat42                off
compat43                off
compat44                off

$ echo $BASH_COMPAT

$ export BASH_COMPAT=51
$ export BASH_COMPAT=99
bash: BASH_COMPAT: 99: compatibility value out of range
$ unset BASH_COMPAT
相关推荐
吴声子夜歌1 天前
Shell编程实例——内务及管理任务(一)
linux·运维·shell
吴声子夜歌1 天前
Shell编程实例——高级脚本编程(一)
linux·运维·网络·shell
吴声子夜歌1 天前
Shell编程实例——bash的配置与自定义(二)
linux·运维·shell
吴声子夜歌2 天前
Shell编程实例——与解析相关的任务(二)
linux·运维·shell
吴声子夜歌2 天前
Shell编程实例——脚本编程的附加特性
linux·运维·shell
云计算练习生2 天前
什么是内核?操作系统内核到底管哪些事
linux·windows·操作系统·内核·shell
吴声子夜歌5 天前
Shell编程实例——bash入门
linux·运维·shell
Swizard5 天前
Linux 日志神器 journalctl 完全指南:彻底替代传统日志查看方式
shell
吴声子夜歌6 天前
Shell编程——数组
linux·运维·shell
吴声子夜歌6 天前
Shell编程——开发规范
linux·运维·shell