2

WSL with Ubuntu 18.04 and GNU bash, version 4.4.20(1)-release (x86_64-pc).

I wish to display a message with a conventionally named color via argument such as -red, or -green, or -blue or anything like this (Without an end user required to define colors with machine syntax).

I don't think that even the modern versions of printf or echo can do that.

I'd prefer a shell-builtin and not installing anything.

Lahor
  • 123
  • 1
  • These are exactly the things I am trying to avoid, if possible, of course... I will gladly update and upgrade my entire system just for built-in named colors. – Lahor Mar 12 '22 at 00:40
  • You could write wrapper functions around printf or echo that takes your color name and turns it into the right ANSI escape code. I don't think there is a CLI tool that supports this (yet). – Panki Mar 12 '22 at 12:12
  • If it's part of a script, the end user wouldn't need to define anything. If it's about helping an end user write code there's nothing stopping you defining the colour names in a file that's included either from that user's login script or even the system one – Chris Davies Mar 12 '22 at 21:34

3 Answers3

3

Would setterm do?

setterm -foreground red
RudiC
  • 8,969
  • How can you make it an echo with a string? – Lahor Mar 12 '22 at 15:29
  • @Lahor if that's what you want, please edit it into your question. You haven't explained in what context you need this (in a terminal? Somewhere else? In a specific app? Just printing strings?). – terdon Mar 12 '22 at 18:32
  • @terdon I just want to print a message in terminal, in a chosen color, by a "human readable" argument such as -red per conventional color name in English... – Lahor Mar 13 '22 at 01:45
2

You can define colour words as variables first and then use them with printf or echo

RED='\033[0;31m'
NONE='\033[0m'  # reset colour attribues
printf "${RED}This is in red ${NONE}\n"

Some colour codes are as follows:

Black        0;30     Dark Gray     1;30
Red          0;31     Light Red     1;31
Green        0;32     Light Green   1;32
Brown/Orange 0;33     Yellow        1;33
Blue         0;34     Light Blue    1;34
Purple       0;35     Light Purple  1;35
Cyan         0;36     Light Cyan    1;36
Light Gray   0;37     White         1;37
0

Example of my code follows, heading to bed, hopefully speaks for itself:

tput_init_linux () { set_fg_color='tput setaf'; reset_color=$(tput sgr0 2>/dev/null); } # terminfo
tput_init_bsd   () { set_fg_color='tput AF';    reset_color=$(tput me   2>/dev/null); } # termcap
tput_init_none  () { set_fg_color=':';          reset_color=;                         } # the null command (:) ignores everything after it

if tput setaf 1 >/dev/null 2>&1; then tput_init_linux || tput_init_none; elif tput AF 1 >/dev/null 2>&1; then tput_init_bsd || tput_init_none; else tput_init_none; fi

no_color () { printf '%s' "$reset_color"; }

colorize () { case "$1" in (red) $set_fg_color 1 ;; (green) $set_fg_color 2 ;; (yellow) $set_fg_color 3 ;; (blue) $set_fg_color 4 ;; (magenta) $set_fg_color 5 ;; (cyan) $set_fg_color 6 ;; (white) $set_fg_color 7 ;; (*) printf '%s\n' "[ERROR] This color ('$1') is not supported by the colorize() function. Quiting!" >&2; exit 1 ;; esac }

print_ok () { colorize green; printf '%s' '[OK] '; no_color; } print_notice () { colorize cyan; printf '%s' '[NOTICE] '; no_color; } print_debug () { colorize yellow; printf '%s' '[DEBUG] ' >&2; no_color; } print_error () { colorize red; printf '%s' '[ERROR] ' >&2; no_color; }