Compare Terminal Capabilities with infocmp

Two terminals that look the same can render colour and cursor moves differently, and infocmp proves it instead of guessing. It inspects a compiled terminfo entry, compares two terminal definitions, and produces a readable source-style description. The installed ncurses infocmp here reports version 6.6.20251230. Allow about fifteen minutes; you need a shell and the ncurses terminal database, and none of the normal examples need elevated privileges.

Checkpoint: This guide reads terminal descriptions only. It does not edit the database, install a definition, or change your terminal settings. The output can contain raw escape sequences, so treat it as diagnostic text, not something to paste into an interactive terminal.

1. Confirm the program and version

Start by confirming which binary your shell will actually run. This matters when a host has both a distribution ncurses and a locally installed one:

$ command -v infocmp
/home/linuxbrew/.linuxbrew/bin/infocmp
$ infocmp -V
ncurses 6.6.20251230

The distribution package can be present without owning the binary your PATH selects. The installed package record is useful context here too:

$ dpkg-query -W -f='${Package} ${Version}\n' ncurses-bin
ncurses-bin 6.4+20240113-1ubuntu2.2

When you are chasing a real mismatch, use the exact binary and database your application uses. A different PATH, TERMINFO or TERMINFO_DIRS can make two apparently identical checks inspect different entries.

2. Print the current terminal entry

With no terminal name, infocmp uses TERM. With zero or one terminal name and no explicit mode, ncurses assumes -I, a terminfo-style source listing. Make the input explicit when you are recording a diagnostic:

$ TERM=xterm infocmp -1 -L
# Reconstructed via infocmp from file: /home/linuxbrew/.linuxbrew/Cellar/ncurses/6.6/share/terminfo/./x/xterm
xterm|xterm terminal emulator (X Window System),
	auto_right_margin,
	back_color_erase,
	backspaces_with_bs,
	...
	columns#80,
	lines#24,
	...

-1 puts one capability per line. -L uses long C variable names, often easier to recognise in program documentation. Omit -L when you need the shorter terminfo capability names used by source files and other ncurses tools.

Checkpoint: If this fails with an unknown terminal type, check TERM and the database search path before touching any files:

$ printf 'TERM=%s\n' "$TERM"
$ infocmp -D
/home/linuxbrew/.linuxbrew/Cellar/ncurses/6.6/share/terminfo
/etc/terminfo
/usr/share/terminfo

3. Compare two entries

Pass the first terminal followed by one or more others. With more than one name and no comparison option, infocmp assumes -d, which lists the capabilities that differ:

$ infocmp -1 -q -d xterm screen
comparing xterm to screen.
	bce: T, F.
	mc5i: T, F.
	npc: T, F.
	acsc: '...', '...'.
	clear: '\E[H\E[2J', '\E[H\E[J'.
	...

The values are ordered like the operands: the first belongs to xterm, the second to screen. The abbreviated -q form drops headings and uses - for absent capabilities and @ for cancelled ones. Without it, missing numeric or string values can appear as NULL, which makes it harder to tell absence from cancellation.

Use the other comparison modes for narrower questions:

$ infocmp -1 -q -c xterm screen
comparing xterm to screen.
	bce= T.
	...

-c lists capabilities common to the entries; -n lists capabilities present in none of them. These are read-only reports. They do not prove an application will behave identically, since applications can use only a subset of the available capabilities and can add their own assumptions on top.

4. Produce a reusable use= description

When two entries are related, -u rewrites the first as a description relative to the later entries. This is handy when you are checking whether a local definition can inherit a generic base:

$ infocmp -1 -u xterm screen
xterm|xterm terminal emulator (X Window System),
	bce, mc5i, npc,
	acsc=..., 
	clear=\E[H\E[2J,
	cnorm=\E[?12l\E[?25h,
	...

The order of the entries after the first matters: tic processes use= entries left to right, so conflicting bases can produce different results depending on that order. Read the generated output as a candidate source description, then review it before compiling anything with tic.

A capability shown with @ means the first entry removes one supplied by a base entry. Do not read that marker as an instruction to delete a file; it is terminfo source syntax printed for review.

5. Choose output formats deliberately

Use -I for terminfo names, -L for long names, and -C for termcap names. If you are converting to termcap, the manual recommends combining -C and -r when you need non-standard capabilities, though the conversion is not guaranteed to round-trip perfectly because termcap has different limits and string syntax. -T removes the generated-text size restriction for testing and analysis, useful for a large entry such as this local xterm definition:

$ infocmp -1 -C -r -T xterm | sed -n '1,12p'
xterm|xterm terminal emulator (X Window System):\
	:am:bs:km:mi:ms:pt:co#80:it#8:li#24:cl=\E[H\E[2J:\
	:...

For compact, machine-oriented output, -0 keeps fields on one line. For a chosen line width, use -w with a number. -f asks infocmp to indent complex conditional strings, while -x includes user-defined capabilities. Prefer -1 for human review and stable diffs, then reach for another format only for the consumer that actually needs it.

6. Inspect alternate databases safely

Environment variables control the normal ncurses search path. For a comparison between two databases, -A selects the directory containing the first entry and -B selects the directory containing the other entries:

$ infocmp -A /path/to/old-terminfo -B /path/to/new-terminfo \
    -d xterm xterm

Replace both placeholder paths with directories you have already verified. This command reads the same terminal name from each location; it does not copy, merge or overwrite either database. If you need to see where the current binary searches, run infocmp -D first.

Do not reach for sudo as a first response to a lookup failure. It can change which environment and home directory are relevant while still leaving a missing or incompatible entry unresolved. Use elevated privileges only when your system permissions genuinely block reading a database you are authorised to inspect.

7. Handle failures and automation

In scripts, check the exit status rather than matching a particular line of output. A missing terminal entry, malformed option combination or unreadable database is a failure even if some diagnostic text got printed. Keep the terminal name in a quoted variable if it comes from input:

$ terminal_name='xterm'
$ if infocmp -q -- "$terminal_name" >/tmp/infocmp-entry.txt; then
>     printf 'entry found: %s\n' "$terminal_name"
> else
>     status=$?
>     printf 'infocmp failed for %s (status %s)\n' "$terminal_name" "$status" >&2
> fi
entry found: xterm

There is no persistent change to undo here. The temporary file in that example can be removed after review with rm -- /tmp/infocmp-entry.txt; check the path first if you adapt the example. Never redirect diagnostic output over a valuable source file, and never feed generated terminal strings to a shell as commands.

Done means