Поддерживают ли кавычки кроме Bash и Zsh цитирование ANSI-C? например, $ 'string'

13

У меня есть сценарий оболочки, который использует следующее, чтобы напечатать зеленую галочку в своем выводе:

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 поддерживают этот стиль цитирования, но я не уверен насчет других.

иван
источник
Да, с тех пор, когда только ksh и его вариации пока поддерживают это. Но IIRC, ANSI-C цитирование будет в следующей спецификации POSIX.
cuonglm
ksh doc: debian ksh (1)
Arthur2e5

Ответы:

12

$'…'это функция ksh93, которая также присутствует в zsh, bash, mksh, FreeBSD sh и в некоторых сборках BusyBox sh (BusyBox ash, собранный с ENABLE_ASH_BASH_COMPAT). Его пока нет в языке POSIX sh. Обычные Bourne-подобные оболочки, у которых его нет, включают dash (который /bin/shпо умолчанию используется в Ubuntu), ksh88, оболочку Bourne, NetBSD sh, yash, производные pdksh, отличные от mksh, и некоторые сборки BusyBox.

Использовать переносимый способ синтаксического анализа обратной косой черты и обратной косой черты в качестве управляющих символов printf. Он присутствует на всех POSIX-совместимых системах.

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

Обратите внимание, что \eэто не портативный. Это поддерживается многими реализациями, printfно не одной в dash¹. Вместо этого используйте восьмеричный код.

¹ Он поддерживается в 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). Оболочка, которая не поддерживает \eэто yash.
Мосви
@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 сделал патч для его поддержки.
Жиль "ТАК - перестань быть злым"
Да, извините, похоже, это патч для Debian (9.7). вот оригинал.
Мосви
0

Степень $'...'поддержки также необходимо учитывать при переносе. В предложении POSIX Folks об этом говорится в POSIX :

Стефан: ksh93 - это оболочка, из которой $ '...' (а $'\uxxxx'[ и$'\Uxxxxxxxx' ] - из zsh: http://www.zsh.org/mla/workers/2003/msg00223.html ) [^]

Из того, что я здесь , на моем Debian яблочко, то ksh2020от AT & T понимает $'\U1F600'. Это единственная "официальная" оболочка Korn, которую я могу получить в этом новом дистрибутиве.

mkshразобрал его, но испортил полностью с U + FFFE. Так как он не жаловался на синтаксическую ошибку, должно быть что-то не так с его пониманием Unicode. Он $'\U01F60'отлично справляется .

Arthur2e5
источник
К сожалению, в результате недавнего переворота ksh2020 исчез. Но да, оригинальный ksh93 поддерживает, $'...'и iirc это был первый, кто это сделал.
Мосви
@ Arthur2e5. ksh2020не от AT & T. Несколько человек, один из Red Hat, несколько лет назад ksh93
взломали