ckbcomp turns an XKB layout into a keymap file the Linux console can load. It touches nothing on your system until you deliberately hand the result to loadkeys, using ckbcomp from console-setup 1.226ubuntu1.1, installed here on Ubuntu.
Allow about fifteen minutes. You need a shell, the console-setup package, and a writable working directory. Everything here is unprivileged until the optional step that loads a keymap into the current virtual console, so keep that boundary clear in your head: compiling a file is reversible, changing the active console is an operational change.
Start by confirming which executable and package version you're using. This is a read-only check and needs no sudo:
$ command -v ckbcomp
/usr/bin/ckbcomp
$ dpkg-query -W -f='${Package} ${Version}\n' console-setup
console-setup 1.226ubuntu1.1
$ ckbcomp --help | sed -n '1,18p'
Usage: ckbcomp [args] [<layout> [<variant> [<option> ...]]]
Where legal args are:
-?,-help Print this message
-charmap <name> Specifies the encoding to use
The installed help lists -ccharmap for compose sequences, which the installed 2011 manpage doesn't mention at all. Treat that as version-specific: follow the help from the binary you're actually running before putting an option into a script.
Checkpoint: the path should be the command you intend to use, and the package query should return a version rather than an error.
Pass a layout name and redirect standard output to a new file. The layout argument here is us:
$ ckbcomp us > us-console.map
$ printf 'exit status: %s\n' "$?"
exit status: 0
$ wc -c us-console.map
122370 us-console.map
The byte count is host and version dependent, so don't copy that number into a test. A zero exit status means the compiler completed; it does not mean the layout matches your physical keyboard or that loading it would be a good idea. The output begins with a generated keymap such as keymaps 0-127 and a long run of keycode lines.
Shell redirection truncates an existing destination before ckbcomp even runs, so use a new filename while testing. If you accidentally create an unwanted file, remove only that known file with rm -- us-console.map; don't use a broad wildcard in a directory holding other keymaps.
Use -layout when you want the command to be self-documenting, or when you're building a script. This compiles the British layout:
$ ckbcomp -layout gb > gb-console.map
$ test -s gb-console.map && echo 'non-empty keymap generated'
non-empty keymap generated
Variants and options are separate parts of the XKB description. The manpage supports the positional form layout variant option... and the explicit forms -variant and -option. Prefer the explicit forms when a command will be reviewed later:
$ ckbcomp -layout us -option caps:escape > us-caps-escape.map
$ grep -m 1 -E 'Escape|Caps_Lock' us-caps-escape.map
keycode 58 = Escape
The exact generated lines vary with the installed XKB data. If a layout, variant or option is misspelled, the compiler may fail while resolving the description. Check the exit status and keep the diagnostic output rather than loading a partial or unexpected file.
Without -charmap, the installed manpage says ckbcomp generates a Unicode keymap, which is the normal choice for a modern console. A non-Unicode map needs a character mapping table from /usr/share/consoletrans; the manpage lists names including ISO-8859-1, ISO-8859-15, CP1251 and KOI8-R.
Choose a charmap only when the program consuming the map and the console encoding actually require it:
$ ckbcomp -charmap ISO-8859-1 -layout us > us-iso8859-1.map
$ test -s us-iso8859-1.map && echo 'non-empty non-Unicode keymap generated'
non-empty non-Unicode keymap generated
$ ls /usr/share/consoletrans/ISO-8859-1
/usr/share/consoletrans/ISO-8859-1
A missing or invented charmap is an error. Don't infer an encoding from the language name alone: the keyboard layout describes key symbols, while the charmap controls how those symbols get represented in the output keymap.
Read the generated file as ordinary text before handing it to another keyboard tool. This is safe and needs no elevated privileges:
$ sed -n '1,8p' gb-console.map
$ grep -n -m 1 '^keycode 1 ' gb-console.map
2:keycode 1 = Escape
Don't expect the output to be short: a normal map contains repeated modifier levels, Unicode values and hundreds of key definitions. What you're checking is that the file exists, is non-empty, starts with keymap data and contains the layout-specific symbols you asked for. A successful compiler exit is not a substitute for checking the result.
Warning: loadkeys changes the keyboard mapping of the current Linux virtual console. It can make normal typing confusing fast, and a poor map can make recovery awkward. Save the compiled file and test from a console where you have another access path, such as SSH or a second terminal, before loading it.
Once you've checked the file and accept the change, loading normally needs elevated privileges:
$ sudo loadkeys ./gb-console.map
There may be no useful output on success. Test a few known keys on that virtual console. If the result is wrong, load a known-good map supplied by your distribution or rerun your normal console setup command. Rebooting may restore the distribution default, but don't rely on that as your only recovery plan: ckbcomp itself does not persist the change and provides no undo command.
Don't use sudo ckbcomp just to compile a file. Elevation is only needed when the destination directory or the later loadkeys operation requires it.
For a missing layout file or an unresolved option, rerun the command without redirecting output so the diagnostic stays visible:
$ ckbcomp -layout NOT-A-LAYOUT
$ printf 'exit status: %s\n' "$?"
exit status: 1
Wording and status can vary by package version. Check spelling, installed XKB data and the search paths. The manpage says included descriptions are searched in directories such as /etc/console-setup/ckb, /usr/share/X11/xkb and /etc/X11/xkb. Add a trusted directory with -I when compiling a deliberately local description:
$ ckbcomp -I /path/to/trusted/xkb -layout custom > custom.map
Don't add an arbitrary directory just to make an error disappear. An included XKB file is part of the input, so inspect it and keep it under the same change control as the command that consumes the compiled map.
ckbcomp path and console-setup version.loadkeys.loadkeys changes the current virtual console and have a recovery path.