У меня есть сценарий оболочки, который использует следующее, чтобы напечатать зеленую галочку в своем выводе:
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 поддерживают этот стиль цитирования, но я не уверен насчет других.
Ответы:
$'…'
это функция 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-совместимых системах.Обратите внимание, что
\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
.\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 сделал патч для его поддержки.Степень
$'...'
поддержки также необходимо учитывать при переносе. В предложении POSIX Folks об этом говорится в POSIX :Из того, что я здесь , на моем Debian яблочко, то
ksh2020
от AT & T понимает$'\U1F600'
. Это единственная "официальная" оболочка Korn, которую я могу получить в этом новом дистрибутиве.mksh
разобрал его, но испортил полностью с U + FFFE. Так как он не жаловался на синтаксическую ошибку, должно быть что-то не так с его пониманием Unicode. Он$'\U01F60'
отлично справляется .источник
$'...'
и iirc это был первый, кто это сделал.ksh2020
не от AT & T. Несколько человек, один из Red Hat, несколько лет назадksh93