18

The command tput has two different options for setting color, setf and setaf, yet both of them seem to work just fine on my computer:

$ tput setf 2 && echo 'Hello world!'
$ tput setaf 2 && echo 'Hello world!'

There seems to be a similar duality with setb and setab.

What is the difference between the two options?

  • 1
    See the terminfo(5) man page that comes with ncurses for details. – Stéphane Chazelas Jun 24 '14 at 21:37
16

setf is limited to only 8 colors. setaf can set up to 256 colors.

(all the following information will be specific to urxvt, as that is my terminal, but the info will be similar to, if not the same, as other terminals)

Both setf and setaf provide a different escape code. You can view this in the following:

# tput setf 2 | xxd  
0000000: 1b5b 3332 6d                             .[32m

# tput setaf 2 | xxd 
0000000: 1b5b 3338 3b35 3b32 6d                   .[38;5;2m

From my urxvt(7) man page:

   "ESC [ Pm m"
       Character Attributes (SGR)
       ...
       Pm = 30 / 40       fg/bg Black
       Pm = 31 / 41       fg/bg Red
       Pm = 32 / 42       fg/bg Green
       Pm = 33 / 43       fg/bg Yellow
       Pm = 34 / 44       fg/bg Blue
       Pm = 35 / 45       fg/bg Magenta
       Pm = 36 / 46       fg/bg Cyan
       Pm = 37 / 47       fg/bg White
       Pm = 38;5 / 48;5   set fg/bg to colour #m (ISO 8613-6)

Thus from the above xxd output, we can see that tput setf 2 uses the Pm = 32, which will set the color to green. tput setaf 2 on the other hand uses the Pm = 38;5, which gets represents the color code defined in ISO 8613-6 (also green).
In ISO 8613-6, colors 0x00-0x07 are the same as the standard colors, and 0x08 - 0x0f are the standard "bold" colors. Once you get to 0x10-0xff you get new colors.

Stolen from wikipedia:

0x00-0x07:  standard colors (as in ESC [ 30..37 m)
0x08-0x0f:  high intensity colors (as in ESC [ 90..97 m)
0x10-0xe7:  6*6*6=216 colors: 16 + 36*r + 6*g + b (0≤r,g,b≤5)
0xe8-0xff:  grayscale from black to white in 24 steps
  • tput doesn't appear to actually use the available ANSI color-sequence ranges, though. For any n > 7, tput setaf n has no effect on the text in my terminal. – Kyle Strand Nov 3 '15 at 18:56
  • Actually, that could be just a quirk of my environment; for me the outputs from tput setf 2 and tput setaf 2 are both .[32m. – Kyle Strand Nov 3 '15 at 18:59
3

From the manual: man 5 terminfo

To change the current foreground or background color on a Tektronix-type terminal, use setaf (set ANSI foreground) and setab (set ANSI background) or setf (set foreground) and setb (set background). These take one parameter, the color number. The SVr4 documentation describes only setaf/setab; the XPG4 draft says that "If the terminal supports ANSI escape sequences to set background and foreground, they should be coded as setaf and setab, respectively. If the terminal supports other escape sequences to set background and foreground, they should be coded as setf and setb, respectively. The vidputs() function and the refresh functions use setaf and setab if they are defined."

So the answer is: setaf means Set ANSI foreground, i.e. use ANSI escape sequences, and setf means Set Foreground (using some escape sequences other than ANSI).

3

The two sets of capabilities use different ordering for red/blue in the list of ANSI colors.

As noted, it is explained in the ncurses terminfo manual page. Some history:

  • Early on (mid-1990s), most available "color" terminal descriptions used setf/setb.
  • There was some confusion with termcap users who used the corresponding Sf/Sb codes rather than setaf/setab (and AF/AB for termcap) — but using the ANSI escape sequences (which work with termcap) rather than using the correct capabilities with the ANSI capabilities.
  • Because of that, you will find terminal entries with the two equated, e.g., mgterm, interix, beterm (as well as several entries in FreeBSD's termcap file, again due to this initial confusion combined with the reluctance of others to amend their programs).

The ANSI setaf/setab were added fairly late in terminfo's history as you can infer from their position in the list of capability strings. Keep in mind that those were added in stages over a few years, and some systems differed (ncurses has some examples such as Caps.hpux to let it be compiled to match those systems). That accounted for the small number of useful terminal descriptions which could be used for reference.

With all of that, the fact that the existing setf/setb strings did not match the ANSI order was not immediately noticed, which led to some fixes in 1998, and the faq Why are red/blue interchanged?.

While it was possible to extend the 8-color ANSI sequence to 16-colors (by supposing that colors 8-15 were brighter versions of 0-7), there was no good reason for inventing a scheme to extend setf/setb past the first 16 colors.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.