I have a shell script that uses the following to print a green checkmark in its output:
col_green="e[32;01m"
col_reset="e[39;49;00m"
echo -e "Done ${col_green}✓${col_reset}"
After reading about Bash’s ANSI-C Quoting, I realized I could use it when setting my color variables and remove the -e flag from my echo.
col_green=$'e[32;01m'
col_reset=$'e[39;49;00m'
echo "Done ${col_green}✓${col_reset}"
This seems appealing, since it means the message prints correctly whether it’s passed to Bash’s builtin echo or the external util /bin/echo (I’m on macOS).
But does this make the script less portable? I know Bash and Zsh support this style of quoting, but I’m not sure about others.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
$'…' is a ksh93 feature that is also present in zsh, bash, mksh, FreeBSD sh and in some builds of BusyBox sh (BusyBox ash built with ENABLE_ASH_BASH_COMPAT). It isn’t present in the POSIX sh language yet. Common Bourne-like shells that don’t have it include dash (which is /bin/sh by default on Ubuntu among others), ksh88, the Bourne shell, NetBSD sh, yash, derivatives of pdksh other than mksh and some builds of BusyBox.
A portable way to get backslash-letter and backslash-octal parsed as control characters is to use printf. It’s present on all POSIX-compliant systems.
esc=$(printf '33') # assuming an ASCII (as opposed to EBCDIC) system
col_green="${esc}[32;01m"
Note that e is not portable. It’s supported by many implementations of printf but not by the one in dash¹. Use the octal code instead.
¹ It is supported in Debian and derivatives that ship at least 0.5.8-2.4, e.g. since Debian stretch and Ubuntu 17.04.
Method 2
The degree of $'...' support also needs to be taken into consideration when porting. The POSIX Folks’ proposal to put this in POSIX sh mentions one in particular:
stephane: ksh93 is the shell $’…’ comes from (while
$'uxxxx'[and$'Uxxxxxxxx'] comes from zsh: http://www.zsh.org/mla/workers/2003/msg00223.html) [^]
From what I got here on my Debian bullseye, the ksh2020 understands $'U1F600'. This is the only “official” Korn shell I can get on this new distro.
mksh parsed it but botched it entirely with a U+FFFE. Since it did not complain about a syntax error there’s gotta be something wrong with it’s understanding of Unicode. It handles $'U01F60' just fine.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0