Extract a Console Font's Unicode Table with psfgettable

psfgettable reads the Unicode character table embedded in a PSF console font and writes it out as a readable list, without touching the font itself. The table is suitable for inspection or for a later psfaddtable workflow.

Allow about ten minutes. You need the kbd utilities and a PSF font file. The examples were checked with kbd 2.6.4-2ubuntu2 and psfgettable from /usr/bin/psfgettable. Reading a font and writing a table in your working directory normally require no elevated privileges.

Checkpoint: This command extracts data. It does not edit the input font, install a font, change the active console or require sudo.

1. Confirm the installed command

Check the binary and package version before relying on a script. The installed manual describes the command as extracting an embedded Unicode character table from a .psf console font into a human-readable ASCII file:

$ command -v psfgettable
/usr/bin/psfgettable
$ dpkg-query -W -f='${Package} ${Version}\n' kbd
kbd 2.6.4-2ubuntu2

The command does not provide a help screen. In this version, psfgettable --help is treated as an input filename and fails with an open-file error. Use the manual's syntax instead:

psfgettable fontfile [outfile]

The first argument is the input font. The optional second argument is the table file. If you omit it, the table is written to standard output.

2. Make a usable PSF input

Many distributions store console fonts compressed under /usr/share/consolefonts. psfgettable expects PSF data, so decompress an archive to a temporary or working file first. Do not overwrite the package-managed font:

$ mkdir -p "$HOME/psf-work"
$ zcat /usr/share/consolefonts/Lat15-Terminus16.psf.gz \
    > "$HOME/psf-work/Lat15-Terminus16.psf"
$ file "$HOME/psf-work/Lat15-Terminus16.psf"
/home/you/psf-work/Lat15-Terminus16.psf: Linux/i386 font, PSF2

The path and file description can differ between distributions. What matters is that the destination exists and contains decompressed PSF data. If you already have an uncompressed font, use that path directly.

Checkpoint: Verify the input before extracting:

$ test -r "$HOME/psf-work/Lat15-Terminus16.psf" && \
    echo 'input is readable'
input is readable

3. Write the table to a new file

Warning: Choose a destination that does not contain useful work. Shell redirection and the optional output argument can replace an existing table without a prompt, so use a new name while testing:

$ psfgettable \
    "$HOME/psf-work/Lat15-Terminus16.psf" \
    "$HOME/psf-work/Lat15-Terminus16.table"
$ sed -n '1,12p' "$HOME/psf-work/Lat15-Terminus16.table"
#
# Character table extracted from font
#
0x000   U+00a9
0x001   U+00ae
0x002   U+00d8
0x003   U+2122
0x004   U+2666 U+25c8 U+fffd
0x005   U+00a4
0x006   U+00a6
0x007   U+2022 U+25cf
0x008   U+00a8

Each mapping starts with a glyph slot such as 0x004, followed by one or more Unicode values. Multiple values on one line are meaningful: one glyph can represent several related characters. Keep the comments and mappings together if another kbd utility will consume the file.

Verify that the output is non-empty and inspect its size:

$ wc -l -c "$HOME/psf-work/Lat15-Terminus16.table"
259 5281 /home/you/psf-work/Lat15-Terminus16.table

Your counts will change with the font. A successful exit status and a non-empty file show that extraction completed; they do not prove that the font is the one you intended to process.

4. Use standard output for a pipeline

With no output argument, the table goes to standard output. This is useful for a quick inspection or for passing the result to a command that reads text. Keep diagnostics separate from the table if you script it:

$ psfgettable \
    "$HOME/psf-work/Lat15-Terminus16.psf" \
    > "$HOME/psf-work/Lat15-Terminus16.stdout.table"
$ cmp "$HOME/psf-work/Lat15-Terminus16.table" \
    "$HOME/psf-work/Lat15-Terminus16.stdout.table"
$ echo 'standard output matches the named output'
standard output matches the named output

The output file is plain text, so less, sed and grep are appropriate inspection tools. Do not treat the table as a font: it contains mappings, not glyph data.

5. Read a font from standard input

A single dash tells psfgettable to read the font from standard input. This avoids creating an intermediate decompressed font when the source is a compressed archive:

$ zcat /usr/share/consolefonts/Lat15-Terminus16.psf.gz \
    | psfgettable - "$HOME/psf-work/from-stdin.table"
$ sed -n '1,6p' "$HOME/psf-work/from-stdin.table"
#
# Character table extracted from font
#
0x000   U+00a9
0x001   U+00ae

Use the dash only for the font input. The optional second argument remains the output file. To send both input and output through a pipeline, use a dash for the output too, then redirect or pipe the resulting table:

$ zcat /usr/share/consolefonts/Lat15-Terminus16.psf.gz \
    | psfgettable - - \
    | sed -n '1,6p'

Tip: Be deliberate about redirection: > truncates its destination before the command runs. If you are replacing a table, write to a new file such as table.new, compare it with the existing file, and only then perform a separately reviewed replacement.

6. Diagnose failures without changing the system

A missing or unreadable input is reported as an open-file error and returns a non-zero status:

$ psfgettable "$HOME/psf-work/missing.psf" \
    "$HOME/psf-work/missing.table"
psfgettable: Unable to open file: /home/you/psf-work/missing.psf: No such file or directory

Check the path and permissions before changing anything:

$ ls -l "$HOME/psf-work/missing.psf"
$ test -r "$HOME/psf-work/Lat15-Terminus16.psf" && echo readable

Recovery: Preserve the original font while investigating; extraction itself has no persistent undo operation because it does not modify the source.

Done means