哪些 shell 支持 ANSI-C 引用?例如 $'字符串'

哪些 shell 支持 ANSI-C 引用?例如 $'字符串'

我有一个 shell 脚本,它使用以下命令在其输出中打印绿色复选标记:

col_green="\e[32;01m"
col_reset="\e[39;49;00m"

echo -e "Done ${col_green}✓${col_reset}"

在阅读了 Bash 的ANSI-C 引用,我意识到我可以在设置颜色变量时使用它并-e从我的回声

col_green=$'\e[32;01m'
col_reset=$'\e[39;49;00m'

echo "Done ${col_green}✓${col_reset}"

这看起来很吸引人,因为这意味着无论消息是否传递到 Bash 的内置函数,它都会正确打印回声或外部实用程序/bin/echo(我在 macOS 上)。

但这是否会降低脚本的可移植性?我知道 Bash 和 Zsh 支持这种引用风格,但我不确定其他的。

答案1

$'…'是一个 ksh93 功能,也存在于 zsh、bash、mksh、FreeBSD sh 和 BusyBox sh 的某些版本中(使用 构建的 BusyBox ash ENABLE_ASH_BASH_COMPAT)。它尚未出现在 POSIX sh 语言中。常见的类似 Bourne 的 shell 没有它,包括 dash(默认/bin/sh情况下在 Ubuntu 等上)、ksh88、Bourne shell、NetBSD sh、yash、除 mksh 之外的 pdksh 的衍生物以及 BusyBox 的一些版本。

将反斜杠字母和反斜杠八进制解析为控制字符的可移植方法是使用printf。它存在于所有符合 POSIX 标准的系统上。

esc=$(printf '\033') # assuming an ASCII (as opposed to EBCDIC) system
col_green="${esc}[32;01m"

请注意,它\e不是便携式的。许多实现都支持它,printf但 dash1 中的实现不支持它。请改用八进制代码。

¹它在 Debian 和至少 0.5.8-2.4 版本的衍生版本中受支持,例如从 Debian Stretch 和 Ubuntu 17.04 开始。

答案2

$'...'移植时还需要考虑支持程度。这POSIX Folks 提议将其放入 POSIX sh特别提到一个:

Stephane: ksh93 是 shell $'...' 来自 (而$'\uxxxx'[$'\Uxxxxxxxx'] 来自 zsh:http://www.zsh.org/mla/workers/2003/msg00223.html) [^]

从我在 Debian bullseye 上得到的信息来看,可以ksh2020理解$'\U1F600'.这是我可以在这个新发行版上获得的唯一“官方”Korn shell。

mksh解析了它,但用 U+FFFE 完全搞砸了。既然它没有抱怨语法错误,那么它对 Unicode 的理解一定有问题。它处理$'\U01F60'得很好。

相关内容