From what I know, a well-behaved command-line program should examine the $TERM
environment variable get the name of the terminal emulator, look up its entry in the terminfo
database, and then use those escape codes to control terminal settings such as colours, fonts, styles, erasing the screen, and setting the cursor position.
However, I'm a lazy programmer, and if I want to make some text green, then by far the easiest thing to do is to embed ANSI escape codes directly in my program:
print("\033[32mhi\033[0m")
Changing the terminal colour this way is simple to implement, frees me from having to learn a new dependency (such as ncurses), frees me from running any external programs (such as tput
), and lets me write my program in any language that has strings, rather than any language that has a terminal library.
The idealist in me thinks that it's always better to rely on a standard than to rely on one particular implementation. My macOS installation comes with over two thousand terminal definitions in /usr/share/terminfo
. The pragmatist, on the other hand, has noticed that everybody has been embedding ANSI codes for years now, and everything seems to be fine.
I commonly see code that avoids using a helper library and just uses ANSI codes directly, or software that just checks if $TERM
is anything other than dumb
, or software that doesn't check $TERM
at all. And I very rarely see anybody complaining about this, or requesting support for other terminal types.
Furthermore, I've seen many, many posts on the Internet that make no mention of any other terminal types or escape codes, referring to the ANSI set as "how to do bold and colours in a terminal". It really seems like all other escape code sets have died out, and that ANSI codes (or ECMA-48 codes, or VT102 codes) have become the de-facto standard that the development community has settled on.
So, my question is: if I'm writing command-line software in 2019, is it safe to assume that it will only be used in terminals that speak ANSI?
Edit: People have proposed calling tput
at runtime to print colours to the screen without having to deal with terminfo at all. This works, and is a good solution in many cases, but in my opinion it introduces an unnecessary runtime cost, as it has to execute a separate binary multiple times right as my program starts.
tput
repeatedly. You store the output of tput in variables and use the variables repeatedly, as in roaima's comment. you might need to switch between green and white text 1000 times but you only need to run tput twice - once for green="$(tput ...)" and once for white="$(tput ...)" – cas Oct 23 '19 at 23:46xterm
,screen
, and the Linux "console". Is that enough reason? – roaima Nov 1 '19 at 17:06dmesg
from spicing up my life with yellow text (on lightgray background), I had to create an/etc/terminal-colors.d
directory and then create an emptydisable
file inside it. You cannot make this stuff up. – mosvy Nov 1 '19 at 22:23