Accessing the bash history with arrow keys

After saving the bash history appropriately (as described in the previous post Bash history – how to get the most out of it) you will also want to make sure that working with the history during the session is as easy as pie. For that you will have to adjust the .inputrc file.

Traditionally the terminal/console would emulate all kinds of behaviors depending on your historical terminal access to the computer/mainframe. This unfortunately led to a combinatoric explosion of possible key events and configurations, which makes the successful configuration of the .inputrc rather tedious and annoying.

All I wanted is to use the arrow keys as well as page up and page down, home and end to navigate the commands and the history.

The bash can do that, no doubt, several decades of programming knowledge have been distilled in it, but making it behave according to my needs, well, that was a matter of patience.

The .inputrc-file contains all the key-stroke specific information to make sure the bash behaves as you want it to. Unfortunately, the syntax of the the key-stroke pattern is completely brain-dead. This is why I’m trying to reproduce here as many of the keys as possible, just so that I don’t have to go on another Internet odyssey to find them all.

The format is as follows:
\e denotes an escape character. What follows is the bash interpretation of the key-code of the escaped character. It looks ugly. You have been warned!

Home: "\e[1~"
End:  "\e[4~"
Delete: "\e[3~"
Insert: "\e[2~"
Ctrl+Home: "\e[1;5H"
Ctrk+End: "\e[1;5F"
PageUp: "\e[5~"
PageDown: "\e[6~"
Ctrl+ArrowRight: "\e[1;5C"
Ctrl+ArrowLeft:" "\e[1;5D"

Thus, knowing these cryptic abbreviations, it is now time to configure the bash to make the arrow keys and PageUp/PageDown keys to search within the history. You simply add the cryptic/brain-dead key stroke combination and the desired effect to your .inputrc-file and pray that it will work.

My .inputrc-file looks something like that:

# allow the use of the Home/End keys
"\e[1~": beginning-of-line
"\e[4~": end-of-line

# allow the use of the Delete/Insert keys
"\e[3~": delete-char
"\e[2~": quoted-insert

# mappings for Ctrl+"page up" and "page down" to step to the beginning/end of the history
"\e[1;5H": beginning-of-history
"\e[1;5F": end-of-history

# alternate mappings for "page up" and "page down" to search the history
"\e[5~": history-search-backward
"\e[6~": history-search-forward

"\e[1;5C": forward-word
"\e[1;5D": backward-word
"\e[5C": forward-word
"\e[5D": backward-word
"\e\e[C": forward-word
"\e\e[D": backward-word

set bell-style visible
set expand-tilde on
set convert-meta off
set input-meta on
set output-meta on
set show-all-if-ambiguous on
set visible-stats on

The cool thing about the history-search-backward and history-search-forward functions is, that they search depending on your cursor position:

If you type for example:

 l+PageUp

it will find the first occurrence of any command starting with l.
Moreover, typing ls -+PageUp, will find the first occurrence of any ‘ls -’ in the history of your commands.

You can keep hitting either the PageUp of PageDown keys to move up or down respectively in the shortened history of the list of all commands beginning with whatever you have typed.

A short note to the various set commands in my .inputrc-file:

  • bell-style: if set to visible, it will flash the console window instead of using an ugly and very annoying beep.
  • expand-tilde: if set to on it will expand ~ to your home directory.
  • show-all-if-ambigous: will show all alternatives as a list, if there is any chance of confusing several options.

For the other options, check the bash man-page. It is very complete.

How can you define your own key combinations in bash?

The above table lists some of the common key combinations that you will use on a modern keyboard. But what, if you want to have your own ones defined?

There are two ways: one that will work, the other one that will send you on a long journey of seeking wisdom on the Internet, combined with a lot of trial and error, and quite possibly giving up in deep frustration.

  1. The easy way to custom bash key combinations:
    If your custom key combination is not used or defined in any way in the bash, then the command line is very forthcoming and verbose. Simply type your key combination and see what is produced. For example, if I typed Ctrl+Shift+Delete on the command line, bash would respond with:

    Ctrl+Shift+Delete: 6~
    Shift+Delete: 2~
    Ctrl+Delete: 5~

    You can take this output and put it, after prefixing it with \e, straight into your .inputrc file to use with any function you want to associate with.

  2. The hard or impossible way to custom key combinations in bash:
    In case your bash does not show any output or does something else, your journey will be more difficult or even impossible. There are many levels at which the custom key combinations could be eaten up or interpreted. From the top of my head I can think of at least 3 relevant levels, probably even more. Assuming you use a graphical user interface, i.e. a X-Window system or any incarnation thereof (Gnome, KDE, whatever) then the first level is the window manager, which will take some of the key combinations away. The second level is the terminal emulation program (i.e. Konsole, XTerm, rxvt etc.). And the third level is the bash itself. If your key combinations get eaten by the window manager or the terminal emulation, you will be probably out of luck, unless you are able to redefine those in the configuration of either window manager or terminal. Or you might consider using other alternatives, if this key combination means so much to you. If the key strokes actually arrive in the bash, then you will have a hard (but at least possible) task of reverse engineering, what the bash actually does with those keys, very often it is not apparent at all. Thus, an Internet search will reveal sometimes the functions applied. Then you have to go through the bash configuration files and search for the use of these functions: there you will most likely find the cryptic/brain-dead key commands as well. If not, you can at least cancel this function, so that the key combination will be output like in the easy way.
    You will gather from the above, that you really, really must want to use your custom key combination, which is already in use for something else, before you go through all the hassle of actually finding it and then being able to redefine it.

Either way, with the built-in command bind you can change or add new bindings to test within the bash session, before you put them into your .inputrc file:

bind -p

will give you a list of all currently defined key bindings.

The command

bind -l

on the other hand, will give you all the possible functions you can use for your key combinations.

More information on bind can be found in the bash reference manual.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current month ye@r day *