Экраны ANSI не работают в `printf`

При попытке использовать цветовые экранирования ANSI из сценария оболочки, я полностью застрял, как escape-последовательности (\e) были дословно напечатаны на выходе.

#!/bin/sh
GREEN="\e[32m"
RED="\e[31m"
CLEAR="\e[0m"
printf "${GREEN}test passed${CLEAR}\n"
printf "${RED}test failed${CLEAR}\n"

Производит

\e[32mtest passed\e[0m
\e[31mtest failed\e[0m

2 ответа

Решение

\e POSIX не распознается sh (как упомянуто honzasp), но \033 является.

GREEN='\033[32m'
CLEAR='\033[0m'
printf "${GREEN}testpassed${CLEAR}\n"

Как правило, безопаснее не расширять параметры внутри первого аргумента, чтобы printf (рассмотрим, например, FOO="hello %s"; printf "$FOO bar \n" baz;). Тем не менее, это требует, чтобы вы вставили фактический escape-символ в ваши параметры, а не строку, которая printf интерпретирует как побег персонажа.

GREEN=$(printf '\033[32m')
CLEAR=$(printf '\033[0m')
printf '%stest passed%s' "$GREEN" "$CLEAR"

Решение заключается в использовании #!/bin/bash вместо #!/bin/sh в первой строке, потому что сырье sh"s printf не понимает побега.

Другие вопросы по тегам