I'd like to exchange Esc and CapsLock in console (not in X, and use xev), how can I do it?

My OS is Ubuntu.

3 Answers 3


The tools to manipulate the keyboard layout on the virtual consoles are loadkeys, dumpkeys and showkey. Read their manpages and inform yourself about their intricacies.

Note that these tools only work in a virtual console, not in a terminal emulator in a graphical environment like gnome. The learn about the difference read this question and answers.

Here is a short guide to do what you want:

  1. Save your current keyboard layout:

     $ dumpkeys > backup.kmap

    In case something goes wrong you might be able restore your keymap using the command:

     $ sudo loadkeys backup.kmap

    If the keyboard is so messed up that you can't even do this then your only option not involving ancient kernel magic is to reboot.

  2. Check which keycodes are assigned to your keys:

     $ showkey

    Now press the ESC key and the CAPSLOCK key. The keycodes should show up on the screen. Note the keycodes. On my system the ESC has the keycode 1 and CAPSLOCK has the keycode 58. showkey will terminate after 10 seconds of inactivity (at least it does on my ubuntu 10.04).

  3. Note the names of the ESC and CAPSLOCK keys from dumpkeys:

     $ dumpkeys | grep 1
     keycode   1 = Escape
     $ dumpkeys | grep 58
     keycode  58 = CtrlL_Lock
  4. Note the keymap line from dumpkeys:

     $ dumpkeys | head -1
     keymaps 0-127
  5. Create a keymap file which switches ESC and CAPSLOCK:

     keymaps 0-127
     keycode   1 = CtrlL_Lock
     keycode  58 = Escape
  6. Load the keymap:

     $ sudo loadkeys swap_esc_capslock.kmap
  7. Test: Testing the CAPSLOCK key is obvious. Just press they CAPSLOCK key and check whether other keys come out capitalized. To test the ESC key you can use CTRL+V followed by ESC. It should print ^[. CTRL+V makes the shell print the next key verbatim instead of interpreting it.

To have this modification load on every reboot, put the following line in your /etc/rc.local file:

/usr/bin/loadkeys /path/to/swap_esc_capslock.kmap

Information gathered from various pages, including, but not limited to:

  • 6
    You can also use sudo setupcon --save to make changes permanent, rather than editing rc.local. That's essentially the same as dumpkeys < /dev/tty1 | gzip > /etc/console-setup/cached.kmap.gz
    – bukzor
    May 21, 2012 at 2:21
  • 1
    It is safer to use /usr/bin/loadkeys in /etc/rc.localsince the path environment variable is not guaranteed to be set at this stage. And sudo is not needed in rc.local. May 7, 2013 at 20:04
  • @AugustKarlstrom The command in rc.local executes every time the system boots. @bukzor's sudo setupcon is not in rc.local, it's a one-time setup command, which replaces the system default keymap, without adding any runtime startup code. Adding loadkeys to rc.local, adds extra start up code and duplicates what was already done by the system default loadkeys. The rc.local method could actually be less safe because it depends on a non-standard path to the keymap.
    – RobertL
    Nov 11, 2015 at 21:04
  • 1
    I cannot verify @bukzor's statement about setupcon. It appears that August made the assumption that the sudo setupcon --save would go into rc.local which I don't think is true, but if it does, you don't need sudo in rc.local. I think we need more info before updating your answer. The main question is "How to install the modified keymap so that it gets loaded automatically during the boot process?" I really don't know which is a better way, rc.local or installing a keymap, or even if installing a keymap will work. I have been researching this lately and I'll check back here.
    – RobertL
    Nov 12, 2015 at 3:21
  • 1
    it is worth noting that such a personal keymap is useful also to redefine the behaviour of keys already treated by the default keymap: when loaded with loadkeys, the directives in the default keymap will be replaced when they conflict with the new directives and conserved otherwise. This way, only changes to the keymap must be specified in the personal keymap. Sep 6, 2018 at 16:17

Use ctrl:nocaps instead of ctrl:swapcaps if you just want to have two capslocks key (capslock by another name is still super useless).

X11: (see also: /usr/share/X11/xkb/rules/base.lst)

sudo vim /etc/default/keyboard
udevadm trigger --subsystem-match=input --action=change
sudo restart lightdm

Text console: (stolen from setupcon)

. /etc/default/console-setup 
. /etc/default/keyboard
ckbcomp $acm_option $rules_option -model "$XKBMODEL" \
            | gzip -9 2>/dev/null >/etc/console-setup/cached.kmap.gz
loadkeys /etc/console-setup/cached.kmap.gz
  • 1
    setupcon is not known on my system, do you have any info about source?
    – NiKiZe
    Aug 1, 2021 at 22:29

On Ubuntu (22.04) the console keys are managed by the systemd service keyboard-setup (runs early - before login). It is defined in /lib/systemd/system/keyboard-setup.service (package: console-setup-linux).

The service will run /lib/console-setup/keyboard-setup.sh which will generate a new keymap with setupcon -k (or use a cached version).

Now setupcon (package: console-setup) is found in both /bin/setupcon and /usr/bin/setupcon; these are the same (shell scripts), given /bin --> /usr/bin.

Without a cached kmap.gz file, setupcon -k generates a gzipped keymap file in /etc/console-setup/. With a name that looks like: cached_.*.kmap.gz. E.g. I have: cached_UTF-8_del.kmap.gz. The generated keymap file is loaded with loadkeys.

Configuration for setupcon is sourced from (both):

  • /etc/default/console_setup
  • /etc/default/keyboard

For setupcon -k, the relevant variables that these configuration files (shell scripts) set, (values are for me):

  • XKBMODEL=pc105

(Note: localectl set-x11-keymap ... writes /etc/default/keyboard. If needed, read man localectl, there are commands to get the possible values for the XKB* variables.)

The configuration values are passed to /bin/ckbcomp, which is a perl script parsing all kind of X-files to generate the keymap (on stdout).

The ckbcomp script allows for user additions. It will add the contents of /etc/console-setup/remap.inc at the end of the generated keymap. (Note: when CHARMAP is not UTF-8, compose.$CHARMAP.inc also gets included before remap.inc).

The remap.inc file has examples and is what you should be using if you want to make the mapping permanent.

So the answer to OP's question would be:

    ## run as root on a console
    cd /etc/console-setup

        echo 'keycode 1 = CtrlL_Lock'
        echo 'keycode 58 = Escape'
    } > remap.inc ## Keep the comments? Use '>> remap.inc'.

    ## Remove cached items, so setupcon -k generates a new keymap.
    rm -f cached_*kmap.gz cached_keyboard_setup.sh


Debian also has the packages console-setup and console-setup-linux. So it probably works there too. I have not personally checked this works on Debian.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .