The advantage of tput
is that it looks up what the terminal can do and how, which allows it to get correct information for your terminal. The downside of tput
is that it looks up what the terminal can do and how, which can lead it to get incorrect information for your terminal.
tput
looks for information in the terminfo database, or on older systems in the termcap database. The way this normally works is that the system sets the TERM
environment variable to a terminal name when the terminal starts. With a physical terminal, this is the job of getty
. With a terminal emulator, this is the job of the terminal emulator program. Programs running in the terminal, including tput
, look up the value of TERM
in the termcap or terminfo database, both of which map terminal names to “capabilities”. Terminal capabilities indicate what the terminal can do and how: whether it can do automatic line wrap, how many columns it has, what character sequence the Left key sends, what character sequence to send to the terminal to move the cursor left, etc.
All this is great because it allows programs and terminals to work independently. The system just has to maintain a file containing the capabilities of each available terminal type. For physical terminals, this file would basically be the driver for the terminal. For terminal emulators, this file should be distributed with the terminal emulator program. (There isn't necessarily one file per terminal type, but that's just an implementation detail which is not relevant here.)
This breaks down when you consider remote logins. Programs such as rlogin
and ssh
are terminal emulators on the server, but all they do is relay to the “real” terminal on the client side. So they don't have their own terminal type, they just transmit the TERM
environment variable, so that remote programs running in a terminal will know the capabilities of the terminal. However, programs running on the server then look up the terminal name on the server's termcap/terminfo database, which may not know about the terminal types available on the client.
In the 1970s, ANSI standardized a set of capabilities which was eventually followed by almost all physical terminals. Terminal emulators have continued following this standard. When all terminals have the same capabilities, the terminal database isn't really useful. So people got into the habit of hard-coding terminal escape sequences, either because they didn't know about the terminal database or simply because it was easier: you can just consult your terminal's documentation or experiment, you don't need to also learn the termcap/terminfo interface.
Furthermore ,in the days when a remote login was usually to another machine on the same site administered by the same people, it wasn't hard to ensure that all systems would know about all other systems' terminals. But on the Internet, this doesn't scale. Today, almost all graphical terminal emulators set TERM
to xterm
, because that's a terminal name that you're sure is known everywhere. Some set TERM
to xterm-256color
, which can get you into trouble on some systems that don't know this name.
The problem with setting TERM
to a value that's widely supported, rather than one that exactly describes the capabilities of the terminal, is that you end up missing out on features that are not present in ancient versions of xterm. For example, ancient xterm only supported 8 colors, so on many systems, the termcap/terminfo database entry for xterm
says that the number of colors is 8. So how do you use other colors? You can define a new terminal name such as xterm-256color
, which many systems do nowadays, but not all. And it isn't even accurate: a modern xterm supports 24-bit colors. So, if you want 256 colors, tput
may get you in trouble with remote logins (assuming you do have a xterm-256color
on your system), and if you want to use 24-bit colors, tput
won't help you.
In conclusion, tput
gives you portability on unusual terminals at the expense of features. Using escape sequences directly can give you portability to the terminals you actually use, without limitation on features.
printf
and ANSI escape sequences, buttput
fails (at least on my box).