Chris F.A. Johnson
Unix shell programming notes

11 November 2011

Screen manipulation codes

Placing text at a specific point on the screen or changing its attributes (making it bold or underlined, or changing its colour, for example), can be accomplished in a shell script without calling any external commands.

Traditionally, screen manipulation is done through the termcap or terminfo database that supplies the information necessary to manipulate any of dozens or even hundreds of types of terminal. The shell interface to the database is an external command, tput.

However, tput's operands are not standardized beyond clear, init, and reset (see the POSIX specification for tput), and there are two largely incompatible sets of instructions.

On some systems, tput uses the termcap database; on others (mostly newer systems) it uses the terminfo database. The commands for the two databases are not the same, and a tput command written for one type of system will usually not work on the other.

On one system, the command to place the cursor at the 20th column on the 10th row is:

tput cup 9 19

On another system, the command is:

tput cm 19 9

These commands will produce the correct output for whatever type of terminal is specified in the TERM variable. (Note: tput starts counting lines and rows at 0.)

However, the plethora of terminal types has, for all intents and purposes, been reduced to a single, standard type. This standard, ISO 6429 (also known as ECMA-48 [PDF], and formerly known as ANSI X3.64 or VT100), is ubiquitous, and terminals that do not support it are few and far between. As a result, it is now feasible to code for a single terminal type. One advantage of this homogeneity is that the necessary coding can be done entirely within the shell.

Escape sequences start with the character ESC (ASCII decimal 27/hex 0x1B/octal 033), and most are followed by [ (left bracket) to make up the Control Sequence Introducer (CSI). The final character of these sequences is in the range ASCII 64 to 126, which includes punctuation marks, @ [ \ ] ^ _ ` { | } ~, and the upper- and lower-case letters.

To set the attributes of text, use $CSI3N;4N;Am, where 3N represents the foreground colour, 4N the background colour and A the attribute. The colours and attributes are numbered from 0 to 7:

NColourAttribute
0black normal
1red bold
2green ?
3yellow italics
4blue underline
5magentablink
6cyan ?
7white reverse

So, to print a line with the bold attribute:

printf '\e[1m%s\e[0m\n' "Hello, world!"

More coming shortly.

Modified 18 Nov 2021