除Bash和Zsh之外的其他外壳程序是否支持ANSI-C引用?例如$'string'


13

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

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

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

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

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

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

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

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


是的,因为目前只有ksh及其变体支持它。但是IIRC,ANSI-C引用将在下一个POSIX规范中出现。
cuonglm

Answers:


12

$'…'是ksh93功能,zsh,bash,mksh,FreeBSD sh和某些BusyBox sh版本(使用内置的BusyBox ash ENABLE_ASH_BASH_COMPAT)中也存在ksh93功能。它尚未以POSIX sh语言提供。没有它的常见的类似于Bourne的shell包括破折号(破折号(/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是不可移植的。它受到printfdash 的许多实现的支持,但没有实现。请改用八进制代码。

¹ 在Debian及其衍生版本至少支持0.5.8-2.4的版本中受支持,例如,自Debian Stretch和Ubuntu 17.04起。


您确定\e不被支持dash吗?dash -c 'printf "\e[1;31m"; type printf; printf "\e[m"'printf is a shell builtin在此处以红色粗体显示(破折号-0.5.8)。不支持的shell \eyash
mosvy

@mosvy \e[1;31mprintf is a shell builtin \e[m在这里打印。Ubuntu 16.04,破折号0.5.8-2.1ubuntu2。在Ubuntu 18.04上以红色横线0.5.8-2.10打印为红色。看起来Ubuntu制作了一个补丁来支持它。
吉尔(Gilles)'所以

是的,很抱歉,这似乎是一个debian(9.7拉伸)补丁。是原始的。
mosvy

0

$'...'移植时还需要考虑支持程度。该POSIX伙计来把这个POSIX sh的提案中提到了一个问题:

stephane:ksh93是外壳程序$'...'来自(而$'\uxxxx'[ $'\Uxxxxxxxx' ]来自zsh:http ://www.zsh.org/mla/workers/2003/msg00223.html )[^]

从我在Debian靶心上得到的信息ksh2020来看,AT&T的了解$'\U1F600'。这是我可以在此新发行版上获得的唯一“官方” Korn外壳。

mksh解析它,但完全用U + FFFE破坏它。因为它没有抱怨语法错误,所以它对Unicode的理解肯定有问题。它处理$'\U01F60'得很好。


不幸的是,由于最近的政变, ksh2020已经消失了。但是是的,原始的ksh93确实支持$'...',iirc是第一个这样做的人。
mosvy

@ Arthur2e5。ksh2020不是来自AT&T。几年前,有几个人(其中一个来自Red Hat)劫持了AT&T AST github树,并声称控制了未来的ksh93发展
fpmurphy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.