Using Readline Functions in Bash
Tutorial – Readline
Readline provides you with a rich set of tools for working with text and moving around quickly and efficiently on the command line.
Try this: Open a terminal window and type the following at the prompt:
ls non-existent_dir
Then move your cursor back to the space between ls
and non-existent_dir
and press Ctrl+K. Next hit Ctrl+Y and see what happens.
Congratulations: You are now using Bash as it was used 30 years ago. Or, to be precise, you are using Bash's Readline [1] interface.
Originally written by Brian Fox, the creator of Bash, Readline is a library for advanced key-jockeying for text-based interfaces like Emacs and, yes, Bash. It provides a set of utilities for cutting and pasting (called "killing" and "yanking" in Readline parlance) before such things were made common in graphical interfaces.
In the examples above, the K in Ctrl+K stands for "kill" and the keyboard shortcut Ctrl+K kills everything to the right of the cursor until the end of the line. The Y stands for "yank" and it pastes whatever was last killed into what is called the kill ring.
One Ring
The kill ring is where killed strings go. Remember that killing is like cutting, so the strings you kill don't really go away. The kill ring is like the desktop's clipboard, but completely independent from it.
The nice thing about the kill ring is that it has a number of slots, usually about 60, so you can store quite a few strings in it, and you can rotate through them when yanking (pasting) them back.
To understand better how it works, try this – type
one two three
onto an empty line in your terminal.
Move the cursor to the beginning of three and press Alt+D. This will erase three from the line. The difference with Ctrl+K is that it deletes until the end of the current word, not the current line. So, if you move your cursor to the beginning of one and press Alt+D, one will disappear into the kill ring, but two will stay.
Finally, move to the beginning of two and press Alt+D to pull it into the kill ring. Now the ring contains two, one, and three in that order: two, the last element you killed, is at the top of the kill ring, then one is underneath two, and three, the first element you killed, is at the bottom. (I know: the metaphor of a ring with a top and a bottom doesn't seem to make much sense right now, but bear with me.)
Hold down Ctrl and press Y as before and two, the top element, pops up on your line. Do the same thing again and two will pop up again. But this time, hold down your Alt key and press Y. Suddenly two becomes one.
You have just taken two off the top of the kill ring, pushed it to the bottom, and the next element has risen to the top instead. In fact, you can press Alt+Y several times, and you will cycle through all the elements in the kill ring. When you reach the last element, you will cycle back to what used to be the first item again. The ring metaphor makes more sense now, right?
Apart from killing and yanking, Readline also supplies functions that allow you to move around on a line. You can of course use the Home key to move to the beginning of a line instead of having to press Ctrl+A, or End instead of using Ctrl+E to move to the end of a line. But in any case, the everyday actions of moving to the beginning or the end of a line, even deleting a character, are all Readline functions mapped to special keys on your keyboard.
Talking of deleting, try this: Say you wanted to kill the FileZilla application but typed firefox by mistake:
killall -s KILL firefox
You could press backspace five times or you could hold down the Alt key and press 5. Your prompt changes to argument mode, showing the argument you entered (5) as you can see in Figure 1.
Now hit Backspace, and Bash will delete five characters, leaving:
killall -s KILL fi
This, by the way, works for regular characters, too. Need to type out eight h's for some reason? Press Alt+8, then H, and… Voila! You just saved yourself five keystrokes.
If you need an argument with double, triple, or more digits (62 h's! 345 backspaces!), press Alt plus a digit while in argument mode (Figure 1). Say you need exactly 853 h's. Press Alt+8, then Alt+5, then Alt+3, and finally H (Figure 2).
Realms and Scripture
Apart from killing separate words or until the end of the line, you can also establish "regions" and copy or kill the characters within those. You do this by setting a "mark" on the line, moving the cursor somewhere else (the position of the cursor is known as the "point"), and then copying or killing the characters between the mark and the point, pushing them to the kill ring.
There is a problem though: The functions of copying or killing regions are not assigned to any key combination by default, so you'll have to implement them yourself.
Do this:
cat /etc/inputrc
What you are seeing is the system-wide configuration file for Bash's Readline defaults. On my machine, it looks like what you can see in Listing 1. In /etc/inputrc
, you can see how certain keyboard combinations are assigned to Readline actions:
Listing 1
/etc/inputrc Example File
# do not bell on tab-completion #set bell-style none set meta-flag on set input-meta on set convert-meta off set output-meta on $if mode=emacs # for linux console and RH/Debian xterm "\e[1~": beginning-of-line "\e[4~": end-of-line "\e[5~": beginning-of-history "\e[6~": end-of-history "\e[7~": beginning-of-line "\e[3~": delete-char "\e[2~": quoted-insert "\e[5C": forward-word "\e[5D": backward-word "\e\e[C": forward-word "\e\e[D": backward-word "\e[1;5C": forward-word "\e[1;5D": backward-word # for rxvt "\e[8~": end-of-line # for non RH/Debian xterm, can't hurt for RH/DEbian xterm "\eOH": beginning-of-line "\eOF": end-of-line # for freebsd console "\e[H": beginning-of-line "\e[F": end-of-line $endif
Here's how to interpret this notation:
\e
followed by a key code is used to link a key code to an action. You can find the key code of a key with Bash'sshowkey
command as explained below.\e
followed by the name of another key means press Esc, let go, and then hit the other key.\eo
, for example, would mean hit Esc and then O.- As we have seen, you can also create keyboard shortcuts by combining Ctrl and Alt with other keys.
\C-
followed by another key means "hold down the Ctrl key while you hit the other key." For example,/C-k
means "hold down Ctrl and hit K" – this will usually erase all the characters from the cursor's position until the end of the line. Note that you can have several of these combos one after another to carry out different tasks, like\C-x\C-r
, which reloads the list of macros into Bash after you have modified them. \C-
followed by the name of more than one key means hold down the Ctrl key while you hit the first key listed. Then, let go of Ctrl and hit the second key listed. For example,\C-xx
means "hold down Ctrl and hit X, let go of Ctrl, and hit X again."\M-key
means use the Alt key instead of Ctrl. It works the same as Ctrl, and an example would beM-3
to enter 3 as an argument for a Readline function.
To create a new key combination for yourself, you don't have to edit /etc/inputrc
, since you can create your own file in your home directory. Let's do that so we have a keyboard shortcut to copy and cut regions to the kill ring.
Fire up your favorite text editor and create a file called .inputrc
in your home directory (see Listing 2).
Listing 2
.inputrc
01 $include /etc/inputrc 02 03 "\C-xc": copy-region-as-kill 04 "\C-xx": kill-region
Line 1 pulls in /etc/inputrc
so that you get all the benefits from the system-wide defaults. Line 3 defines a new keyboard shortcut. In this case, you are associating the Ctrl+X and then C combination with Readline's copy-region-as-kill
function. Line 4 is the same thing, except you are associating the Ctrl+X and then X combination with the kill-region
function. For the record, there is a complete list of Bash's Readline functions in the online documentation [2].
Let's try it out. Save .inputrc
, exit your editor and press Ctrl+X and Ctrl+R so the changes are applied for the current shell. If there is anything wrong with your script, Readline will show an error.
When everything is okay, type a long line into your terminal:
wget "https://somedomain.com/somefile" && echo "Downloaded successfully"
Move your cursor to the s of somefile and press Ctrl+@. This sets the mark on the s. Now move your cursor to the double quotes after somefile and press Ctrl+X and then C, the keyboard combination you set up in .inputrc
to copy the region to the kill ring.
It may seem that nothing has happened, but now move the cursor to after Downloaded and press Ctrl+Y to yank the latest item on the kill ring into the line. Hey presto!:
wget "https://somedomain.com/somefile" && echo "Downloaded somefile successfully"
If instead of using the keyboard shortcut for copying, you had held down Ctrl and pressed X and then let go of Ctrl and pressed X again, you would've cut the region between the mark and the point.
Apart from associating shortcuts with Readline's predefined functions, you can also create your own functions and keyboard shortcuts for them.
Open .inputrc
in your text editor again and add the following line:
"\el": "ls\015"
This creates a keyboard combination (press Esc, let go, and then press L) that lists the content of the current directory. The \015
part of the command is the code for Carriage Return (Enter) in ASCII.
You can find more key codes using the shell's showkey -a
command (Figure 3).
For example, suppose you wanted to list the contents of the current directory by pressing Alt+Right Arrow. Run showkey -a
and hold down Alt and press the right arrow to discover the key code (Listing 3).
Listing 3
Getting Key Codes
01 $ sudo showkey -a 02 Press any keys - Ctrl-D will terminate this program 03 ^[[1;3C 27 0033 0x1b 04 91 0133 0x5b 05 ...
What you're interested in is the first line showkey
spits out after pressing Alt+ Arrow Right. In Listing 3, that would be line 3. Focus on the bit that says ^[[1;3C
.
Press Ctrl+D to exit showkey
and open .inputrc
in your text editor.
Change the line that says
"\el": "ls\015"
to
"\e[1;3C": "ls\015"
Save the file and reload the Readline macros (Ctrl+X, Ctrl+R).
Now hold down Alt, press the Right Arrow key on your keyboard, and the current directory will list.
History
The Readline set of functions also covers Bash's history. Every time you press the Up Arrow to navigate to a command you have used earlier, you are invoking a Readline function. But there is more to finding entries than just pressing the Up Arrow over and over.
Try this: Start on an empty line and press Ctrl+R. Bash will enter incremental search mode. This means you can start typing in some of the letters of the command you are looking for and Bash will search upwards through the history and show you matches as you type (Figure 4).
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Gnome 47.2 Now Available
Gnome 47.2 is now available for general use but don't expect much in the way of newness, as this is all about improvements and bug fixes.
-
Latest Cinnamon Desktop Releases with a Bold New Look
Just in time for the holidays, the developer of the Cinnamon desktop has shipped a new release to help spice up your eggnog with new features and a new look.
-
Armbian 24.11 Released with Expanded Hardware Support
If you've been waiting for Armbian to support OrangePi 5 Max and Radxa ROCK 5B+, the wait is over.
-
SUSE Renames Several Products for Better Name Recognition
SUSE has been a very powerful player in the European market, but it knows it must branch out to gain serious traction. Will a name change do the trick?
-
ESET Discovers New Linux Malware
WolfsBane is an all-in-one malware that has hit the Linux operating system and includes a dropper, a launcher, and a backdoor.
-
New Linux Kernel Patch Allows Forcing a CPU Mitigation
Even when CPU mitigations can consume precious CPU cycles, it might not be a bad idea to allow users to enable them, even if your machine isn't vulnerable.
-
Red Hat Enterprise Linux 9.5 Released
Notify your friends, loved ones, and colleagues that the latest version of RHEL is available with plenty of enhancements.
-
Linux Sees Massive Performance Increase from a Single Line of Code
With one line of code, Intel was able to increase the performance of the Linux kernel by 4,000 percent.
-
Fedora KDE Approved as an Official Spin
If you prefer the Plasma desktop environment and the Fedora distribution, you're in luck because there's now an official spin that is listed on the same level as the Fedora Workstation edition.
-
New Steam Client Ups the Ante for Linux
The latest release from Steam has some pretty cool tricks up its sleeve.