web-dev-qa-db-ja.com

BashとZsh以外のシェルはANSI-Cクォートをサポートしていますか?例えば$ '文字列'

以下を使用して出力に緑色のチェックマークを出力するシェルスクリプトがあります。

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

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

Bashの ANSI-C Quoting について読んだ後、色変数を設定して-eフラグをecho

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がこのスタイルの引用をサポートしていることは知っていますが、他のスタイルについてはわかりません。

13
ivan

$'…'は、zsh、bash、mksh、FreeBSD sh、およびBusyBox shの一部のビルド(ENABLE_ASH_BASH_COMPAT)。 POSIXsh言語にはまだ存在していません。それを持たない一般的なボーンのようなシェルにはダッシュが含まれます(これは/bin/sh特にUbuntuのデフォルト)、ksh88、Bourne Shell、NetBSD sh、yash、mksh以外のpdkshの派生物、およびBusyBoxの一部のビルド。

制御文字としてバックスラッシュ文字とバックスラッシュ8進数を解析するための移植可能な方法は、 printf を使用することです。これは、すべてのPOSIX準拠システムに存在します。

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

ご了承ください \eは移植性がありません。 printfの多くの実装でサポートされていますが、ダッシュ¹の実装ではサポートされていません。代わりに8進コードを使用してください。

¹ これは、Debianおよび少なくとも0.5.8-2.4を出荷する派生物でサポートされています。 DebianストレッチとUbuntu17.04以降。

移植するときは、$'...'サポートの程度も考慮する必要があります。 これをPOSIX shに入れるというPOSIX Folksの提案 は特に1つ言及しています:

stephane:ksh93はシェルです$ '...'は(while $'\uxxxx' [and $'\Uxxxxxxxx']はzshから取得されます: http://www.zsh.org/mla/workers/2003/msg00223.html )[^]

私がDebianブルズアイでここで得たものから、AT&Tのksh2020$'\U1F600'を理解しています。これは、この新しいディストリビューションに乗ることができる唯一の「公式」KornShellです。

mkshはそれを解析しましたが、U + FFFEで完全に失敗しました。構文エラーについて文句を言わなかったので、Unicodeの理解に何か問題があるはずです。 $'\U01F60'を問題なく処理します。

0
Arthur2e5