除了 Bash 和 Zsh 之外的 shell 是否支持 ANSI-C 引用?例如 $'string'

iva*_*van 14 shell string quoting escape-characters portability

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

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

echo -e "Done ${col_green}?${col_reset}"
Run Code Online (Sandbox Code Playgroud)

在阅读了 Bash 的ANSI-C Quoting 之后,我意识到我可以在设置颜色变量时使用它并-e从我的echo 中删除标志。

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

echo "Done ${col_green}?${col_reset}"
Run Code Online (Sandbox Code Playgroud)

这似乎很吸引人,因为这意味着无论是传递给 Bash 的内置echo还是外部 util /bin/echo(我使用的是 macOS),消息都能正确打印。

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

Gil*_*il' 18

$'…'是一个 ksh93 特性,它也存在于 zsh、bash、mksh、FreeBSD sh 和 BusyBox sh 的一些构建中(BusyBox ash 使用 构建ENABLE_ASH_BASH_COMPAT)。它尚不存在于 POSIX sh 语言中。没有它的常见 Bourne-like 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"
Run Code Online (Sandbox Code Playgroud)

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

¹它在 Debian 和至少发布 0.5.8-2.4 的衍生产品中受支持,例如自 Debian 延伸和 Ubuntu 17.04 起。