Is there any objective benefit to escape sequences over tput?

tput can handle expressions (for instance in sgr and setaf) which the typical shell-scripter would find less than usable. To get an idea of what is involved, see the output from infocmp with the -f (formatting) option applied. Here is one of examples using those strings from xterm's terminfo descriptions:

xterm-16color|xterm with 16 colors,
        colors#16,
        pairs#256,
        setab=\E[
                %?
                        %p1%{8}%<
                        %t%p1%{40}%+
                %e
                        %p1%{92}%+
                %;%dm,
        setaf=\E[
                %?
                        %p1%{8}%<
                        %t%p1%{30}%+
                %e
                        %p1%{82}%+
                %;%dm,
        setb=
                %p1%{8}%/%{6}%*%{4}%+\E[%d%p1%{8}%m%Pa
                %?%ga%{1}%=
                        %t4
                %e%ga%{3}%=
                        %t6
                %e%ga%{4}%=
                        %t1
                %e%ga%{6}%=
                        %t3
                %e%ga%d
                %;
                m,
        setf=
                %p1%{8}%/%{6}%*%{3}%+\E[%d%p1%{8}%m%Pa
                %?%ga%{1}%=
                        %t4
                %e%ga%{3}%=
                        %t6
                %e%ga%{4}%=
                        %t1
                %e%ga%{6}%=
                        %t3
                %e%ga%d
                %;
                m,
        use=xterm+256color,
        use=xterm-new,

The formatting splits things up - a script or program to do the same would have to follow those twists and turns. Most people give up and just use the easiest strings.

The 16-color feature is borrowed from IBM aixterm, which maps 16 codes each for foreground and background onto two ranges;

  • foreground onto 30-37, and 90-97
  • background onto 40-47, and 100-107

A simple script

#!/bin/sh
TERM=xterm-16color
export TERM
printf '    %12s %12s\n' Foreground Background
for n in $(seq 0 15)
do
    F=$(tput setaf $n | cat -v)
    B=$(tput setab $n | cat -v)
    printf '%2d  %12s %12s\n' $n "$F" "$B"
done

and output show how it works:

      Foreground   Background
 0        ^[[30m       ^[[40m
 1        ^[[31m       ^[[41m
 2        ^[[32m       ^[[42m
 3        ^[[33m       ^[[43m
 4        ^[[34m       ^[[44m
 5        ^[[35m       ^[[45m
 6        ^[[36m       ^[[46m
 7        ^[[37m       ^[[47m
 8        ^[[90m      ^[[100m
 9        ^[[91m      ^[[101m
10        ^[[92m      ^[[102m
11        ^[[93m      ^[[103m
12        ^[[94m      ^[[104m
13        ^[[95m      ^[[105m
14        ^[[96m      ^[[106m
15        ^[[97m      ^[[107m

The numbers are split up because aixterm uses the 30-37 and 40-47 ranges to match ECMA-48 (also known as "ANSI") colors, and uses the 90-107 range for codes not defined in the standard.

Here is a screenshot with xterm using TERM=xterm-16color, where you can see the effect.

enter image description here

Further reading:

  • infocmp - compare or print out terminfo descriptions
  • tput, reset - initialize a terminal or query terminfo database
  • ECMA-48: Control Functions for Coded Character Sets
  • aixterm Command
  • Aren't bright colors the same as bold? (XTerm FAQ)

Coming from a time when UNIX platforms could have a variety of devices attached to them, I still much prefer tput and its friends over literal escape sequences.

I think the real reason is that most people simply don't know about tput and its associated terminfo/termcap files and libraries.